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

#ifndef _DBACORE_DATACOLUMN_HXX_
#include "CRowSetDataColumn.hxx"
#endif
#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
#include "dbastrings.hrc"
#endif
#ifndef _DBASHARED_APITOOLS_HXX_
#include "apitools.hxx"
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace dbaccess;
using namespace comphelper;
using namespace connectivity;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
//  using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace cppu;
using namespace osl;

DBG_NAME(ORowSetDataColumn);
// -------------------------------------------------------------------------
ORowSetDataColumn::ORowSetDataColumn(   const Reference < XResultSetMetaData >& _xMetaData,
                                      const Reference < XRow >& _xRow,
                                      const Reference < XRowUpdate >& _xRowUpdate,
                                      sal_Int32 _nPos,
                                      const ::rtl::OUString& _rDescription,
                                      const ORowSetCacheIterator& _rColumnValue,
                                      ORowSetMatrix::iterator& _rEnd)
    : ODataColumn(_xMetaData,_xRow,_xRowUpdate,_nPos)
    ,m_aDescription(_rDescription)
    ,m_aColumnValue(_rColumnValue)
    ,m_rEnd(_rEnd)
{
    DBG_CTOR(ORowSetDataColumn,NULL);
}
// -------------------------------------------------------------------------
ORowSetDataColumn::~ORowSetDataColumn()
{
    DBG_DTOR(ORowSetDataColumn,NULL);
}
// -------------------------------------------------------------------------
// comphelper::OPropertyArrayUsageHelper
//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper* ORowSetDataColumn::createArrayHelper( ) const
{
    BEGIN_PROPERTY_HELPER(30)
        DECL_PROP2(ALIGN,                   sal_Int32,          BOUND,MAYBEVOID);
        DECL_PROP1(CATALOGNAME,             ::rtl::OUString,    READONLY);
        DECL_PROP2(CONTROLDEFAULT,          ::rtl::OUString,    BOUND,MAYBEVOID);
        DECL_PROP1_IFACE(CONTROLMODEL,      XPropertySet,       BOUND       );
        DECL_PROP1(DESCRIPTION,             ::rtl::OUString,    READONLY);
        DECL_PROP1(DISPLAYSIZE,             sal_Int32,          READONLY);
        DECL_PROP2(NUMBERFORMAT,            sal_Int32,          BOUND,MAYBEVOID);
        DECL_PROP2(HELPTEXT,            ::rtl::OUString,    BOUND,MAYBEVOID);
        DECL_PROP1_BOOL(HIDDEN,                             BOUND);
        DECL_PROP1_BOOL(ISAUTOINCREMENT,                        READONLY);
        DECL_PROP1_BOOL(ISCASESENSITIVE,                        READONLY);
        DECL_PROP1_BOOL(ISCURRENCY,                             READONLY);
        DECL_PROP1_BOOL(ISDEFINITELYWRITABLE,                   READONLY);
        DECL_PROP1(ISNULLABLE,              sal_Int32,          READONLY);
        DECL_PROP1_BOOL(ISREADONLY,                             READONLY);
        DECL_PROP1_BOOL(ISSEARCHABLE,                           READONLY);
        DECL_PROP1_BOOL(ISSIGNED,                               READONLY);
        DECL_PROP1_BOOL(ISWRITABLE,                             READONLY);
        DECL_PROP1(LABEL,                   ::rtl::OUString,    READONLY);
        DECL_PROP1(NAME,                    ::rtl::OUString,    READONLY);
        DECL_PROP1(PRECISION,               sal_Int32,          READONLY);
        DECL_PROP2(RELATIVEPOSITION,    sal_Int32,          BOUND, MAYBEVOID);
        DECL_PROP1(SCALE,                   sal_Int32,          READONLY);
        DECL_PROP1(SCHEMANAME,              ::rtl::OUString,    READONLY);
        DECL_PROP1(SERVICENAME,             ::rtl::OUString,    READONLY);
        DECL_PROP1(TABLENAME,               ::rtl::OUString,    READONLY);
        DECL_PROP1(TYPE,                    sal_Int32,          READONLY);
        DECL_PROP1(TYPENAME,                ::rtl::OUString,    READONLY);
        DECL_PROP1(VALUE,                   Any,                BOUND);
        DECL_PROP1(WIDTH,                   sal_Int32,          MAYBEVOID);
    END_PROPERTY_HELPER();
}

// cppu::OPropertySetHelper
//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& ORowSetDataColumn::getInfoHelper()
{
    return *static_cast< ::comphelper::OPropertyArrayUsageHelper< ORowSetDataColumn >* >(this)->getArrayHelper();
}
// -------------------------------------------------------------------------
void SAL_CALL ORowSetDataColumn::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
{
    switch(nHandle)
    {
        case PROPERTY_ID_DESCRIPTION:
            rValue <<= m_aDescription;
            break;
        case PROPERTY_ID_ALIGN:
        case PROPERTY_ID_NUMBERFORMAT:
        case PROPERTY_ID_RELATIVEPOSITION:
        case PROPERTY_ID_WIDTH:
        case PROPERTY_ID_HIDDEN:
        case PROPERTY_ID_CONTROLMODEL:
        case PROPERTY_ID_HELPTEXT:
        case PROPERTY_ID_CONTROLDEFAULT:
            OColumnSettings::getFastPropertyValue( rValue, nHandle );
            break;
        case PROPERTY_ID_VALUE:
            if(!m_aColumnValue.isNull() && m_aColumnValue != m_rEnd && m_aColumnValue->isValid())
            {
                ORowSetRow aRow = *m_aColumnValue;
                OSL_ENSURE((sal_Int32)aRow->size() > m_nPos,"Pos is greater than size of vector");
                rValue = (*(*m_aColumnValue))[m_nPos].makeAny();
            }
            break;
        default:
            ODataColumn::getFastPropertyValue(rValue,nHandle);
    }
}
// -------------------------------------------------------------------------
void SAL_CALL ORowSetDataColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue )throw (Exception)
{
    switch(nHandle)
    {
        case PROPERTY_ID_ALIGN:
        case PROPERTY_ID_NUMBERFORMAT:
        case PROPERTY_ID_RELATIVEPOSITION:
        case PROPERTY_ID_WIDTH:
        case PROPERTY_ID_HIDDEN:
        case PROPERTY_ID_CONTROLMODEL:
        case PROPERTY_ID_HELPTEXT:
        case PROPERTY_ID_CONTROLDEFAULT:
            OColumnSettings::setFastPropertyValue_NoBroadcast( nHandle, rValue );
            break;
        case PROPERTY_ID_VALUE:
            updateObject(rValue);
            break;
        default:
            ODataColumn::setFastPropertyValue_NoBroadcast(nHandle,rValue );
    }
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL ORowSetDataColumn::convertFastPropertyValue( Any & rConvertedValue,
                                                            Any & rOldValue,
                                                            sal_Int32 nHandle,
                                                            const Any& rValue ) throw (IllegalArgumentException)
{
    sal_Bool bModified = sal_False;
    switch(nHandle)
    {
        case PROPERTY_ID_ALIGN:
        case PROPERTY_ID_NUMBERFORMAT:
        case PROPERTY_ID_RELATIVEPOSITION:
        case PROPERTY_ID_WIDTH:
        case PROPERTY_ID_HIDDEN:
        case PROPERTY_ID_CONTROLMODEL:
        case PROPERTY_ID_HELPTEXT:
        case PROPERTY_ID_CONTROLDEFAULT:
            bModified = OColumnSettings::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
            break;
        case PROPERTY_ID_VALUE:
            rConvertedValue = rValue;
            getFastPropertyValue(rOldValue, PROPERTY_ID_VALUE);
            bModified = !::comphelper::compare(rConvertedValue, rOldValue);
            break;
        default:
            bModified = ODataColumn::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);

    }

    return bModified;
}
//--------------------------------------------------------------------------
Sequence< sal_Int8 > ORowSetDataColumn::getImplementationId() throw (RuntimeException)
{
    static OImplementationId * pId = 0;
    if (! pId)
    {
        MutexGuard aGuard( Mutex::getGlobalMutex() );
        if (! pId)
        {
            static OImplementationId aId;
            pId = &aId;
        }
    }
    return pId->getImplementationId();
}
// -------------------------------------------------------------------------
void ORowSetDataColumn::fireValueChange(const ORowSetValue& _rOldValue)
{
    if(!m_aColumnValue.isNull() && m_aColumnValue != m_rEnd && m_aColumnValue->isValid() && (!((*(*m_aColumnValue))[m_nPos] == _rOldValue)))
    {
        sal_Int32 nHandle = PROPERTY_ID_VALUE;
        m_aOldValue = _rOldValue.makeAny();
        Any aNew = (*(*m_aColumnValue))[m_nPos].makeAny();

        fire(&nHandle, &aNew, &m_aOldValue, 1, sal_False );
    }
}
// -----------------------------------------------------------------------------
DBG_NAME(ORowSetDataColumns )
ORowSetDataColumns::ORowSetDataColumns(
                sal_Bool _bCase,
                const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,
                ::cppu::OWeakObject& _rParent,
                ::osl::Mutex& _rMutex,
                const ::std::vector< ::rtl::OUString> &_rVector
                ) : connectivity::sdbcx::OCollection(_rParent,_bCase,_rMutex,_rVector)
                ,m_aColumns(_rColumns)
{
    DBG_CTOR(ORowSetDataColumns ,NULL);
}
// -----------------------------------------------------------------------------
ORowSetDataColumns::~ORowSetDataColumns()
{
    DBG_DTOR(ORowSetDataColumns ,NULL);
}
// -----------------------------------------------------------------------------
sdbcx::ObjectType ORowSetDataColumns::createObject(const ::rtl::OUString& _rName)
{
    connectivity::sdbcx::ObjectType xNamed;

    ::comphelper::UStringMixEqual aCase(isCaseSensitive());
    ::connectivity::OSQLColumns::const_iterator first =  ::connectivity::find(m_aColumns->begin(),m_aColumns->end(),_rName,aCase);
    if(first != m_aColumns->end())
        xNamed.set(*first,UNO_QUERY);

    return xNamed;
}
// -----------------------------------------------------------------------------
void SAL_CALL ORowSetDataColumns::disposing(void)
{
    //  clear_NoDispose();
    ORowSetDataColumns_BASE::disposing();
    m_aColumns = NULL;
    //  m_aColumns.clear();
}
// -----------------------------------------------------------------------------
void ORowSetDataColumns::assign(const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,const ::std::vector< ::rtl::OUString> &_rVector)
{
    m_aColumns = _rColumns;
    reFill(_rVector);
}
// -----------------------------------------------------------------------------
void ORowSetDataColumns::impl_refresh() throw(::com::sun::star::uno::RuntimeException)
{
}
// -----------------------------------------------------------------------------

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

#ifndef _DBACORE_DATACOLUMN_HXX_
#include "CRowSetDataColumn.hxx"
#endif
#ifndef DBACCESS_SHARED_DBASTRINGS_HRC
#include "dbastrings.hrc"
#endif
#ifndef _DBASHARED_APITOOLS_HXX_
#include "apitools.hxx"
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_
#include <com/sun/star/beans/PropertyAttribute.hpp>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace dbaccess;
using namespace comphelper;
using namespace connectivity;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
//  using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace cppu;
using namespace osl;

DBG_NAME(ORowSetDataColumn);
// -------------------------------------------------------------------------
ORowSetDataColumn::ORowSetDataColumn(   const Reference < XResultSetMetaData >& _xMetaData,
                                      const Reference < XRow >& _xRow,
                                      const Reference < XRowUpdate >& _xRowUpdate,
                                      sal_Int32 _nPos,
                                      const ::rtl::OUString& _rDescription,
                                      const ORowSetCacheIterator& _rColumnValue,
                                      ORowSetMatrix::iterator& _rEnd)
    : ODataColumn(_xMetaData,_xRow,_xRowUpdate,_nPos)
    ,m_aDescription(_rDescription)
    ,m_aColumnValue(_rColumnValue)
    ,m_rEnd(_rEnd)
{
    DBG_CTOR(ORowSetDataColumn,NULL);
}
// -------------------------------------------------------------------------
ORowSetDataColumn::~ORowSetDataColumn()
{
    DBG_DTOR(ORowSetDataColumn,NULL);
}
// -------------------------------------------------------------------------
// comphelper::OPropertyArrayUsageHelper
//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper* ORowSetDataColumn::createArrayHelper( ) const
{
    BEGIN_PROPERTY_HELPER(30)
        DECL_PROP2(ALIGN,                   sal_Int32,          BOUND,MAYBEVOID);
        DECL_PROP1(CATALOGNAME,             ::rtl::OUString,    READONLY);
        DECL_PROP2(CONTROLDEFAULT,          ::rtl::OUString,    BOUND,MAYBEVOID);
        DECL_PROP1_IFACE(CONTROLMODEL,      XPropertySet,       BOUND       );
        DECL_PROP1(DESCRIPTION,             ::rtl::OUString,    READONLY);
        DECL_PROP1(DISPLAYSIZE,             sal_Int32,          READONLY);
        DECL_PROP2(NUMBERFORMAT,            sal_Int32,          BOUND,MAYBEVOID);
        DECL_PROP2(HELPTEXT,            ::rtl::OUString,    BOUND,MAYBEVOID);
        DECL_PROP1_BOOL(HIDDEN,                             BOUND);
        DECL_PROP1_BOOL(ISAUTOINCREMENT,                        READONLY);
        DECL_PROP1_BOOL(ISCASESENSITIVE,                        READONLY);
        DECL_PROP1_BOOL(ISCURRENCY,                             READONLY);
        DECL_PROP1_BOOL(ISDEFINITELYWRITABLE,                   READONLY);
        DECL_PROP1(ISNULLABLE,              sal_Int32,          READONLY);
        DECL_PROP1_BOOL(ISREADONLY,                             READONLY);
        DECL_PROP1_BOOL(ISSEARCHABLE,                           READONLY);
        DECL_PROP1_BOOL(ISSIGNED,                               READONLY);
        DECL_PROP1_BOOL(ISWRITABLE,                             READONLY);
        DECL_PROP1(LABEL,                   ::rtl::OUString,    READONLY);
        DECL_PROP1(NAME,                    ::rtl::OUString,    READONLY);
        DECL_PROP1(PRECISION,               sal_Int32,          READONLY);
        DECL_PROP2(RELATIVEPOSITION,    sal_Int32,          BOUND, MAYBEVOID);
        DECL_PROP1(SCALE,                   sal_Int32,          READONLY);
        DECL_PROP1(SCHEMANAME,              ::rtl::OUString,    READONLY);
        DECL_PROP1(SERVICENAME,             ::rtl::OUString,    READONLY);
        DECL_PROP1(TABLENAME,               ::rtl::OUString,    READONLY);
        DECL_PROP1(TYPE,                    sal_Int32,          READONLY);
        DECL_PROP1(TYPENAME,                ::rtl::OUString,    READONLY);
        DECL_PROP1(VALUE,                   Any,                BOUND);
        DECL_PROP1(WIDTH,                   sal_Int32,          MAYBEVOID);
    END_PROPERTY_HELPER();
}

// cppu::OPropertySetHelper
//------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& ORowSetDataColumn::getInfoHelper()
{
    return *static_cast< ::comphelper::OPropertyArrayUsageHelper< ORowSetDataColumn >* >(this)->getArrayHelper();
}
// -------------------------------------------------------------------------
void SAL_CALL ORowSetDataColumn::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
{
    switch(nHandle)
    {
        case PROPERTY_ID_DESCRIPTION:
            rValue <<= m_aDescription;
            break;
        case PROPERTY_ID_ALIGN:
        case PROPERTY_ID_NUMBERFORMAT:
        case PROPERTY_ID_RELATIVEPOSITION:
        case PROPERTY_ID_WIDTH:
        case PROPERTY_ID_HIDDEN:
        case PROPERTY_ID_CONTROLMODEL:
        case PROPERTY_ID_HELPTEXT:
        case PROPERTY_ID_CONTROLDEFAULT:
            OColumnSettings::getFastPropertyValue( rValue, nHandle );
            break;
        case PROPERTY_ID_VALUE:
            if(!m_aColumnValue.isNull() && m_aColumnValue != m_rEnd && m_aColumnValue->isValid())
            {
                ORowSetRow aRow = *m_aColumnValue;
                OSL_ENSURE((sal_Int32)aRow->size() > m_nPos,"Pos is greater than size of vector");
                rValue = (*(*m_aColumnValue))[m_nPos].makeAny();
            }
            break;
        default:
            ODataColumn::getFastPropertyValue(rValue,nHandle);
    }
}
// -------------------------------------------------------------------------
void SAL_CALL ORowSetDataColumn::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue )throw (Exception)
{
    switch(nHandle)
    {
        case PROPERTY_ID_ALIGN:
        case PROPERTY_ID_NUMBERFORMAT:
        case PROPERTY_ID_RELATIVEPOSITION:
        case PROPERTY_ID_WIDTH:
        case PROPERTY_ID_HIDDEN:
        case PROPERTY_ID_CONTROLMODEL:
        case PROPERTY_ID_HELPTEXT:
        case PROPERTY_ID_CONTROLDEFAULT:
            OColumnSettings::setFastPropertyValue_NoBroadcast( nHandle, rValue );
            break;
        case PROPERTY_ID_VALUE:
            updateObject(rValue);
            break;
        default:
            ODataColumn::setFastPropertyValue_NoBroadcast(nHandle,rValue );
    }
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL ORowSetDataColumn::convertFastPropertyValue( Any & rConvertedValue,
                                                            Any & rOldValue,
                                                            sal_Int32 nHandle,
                                                            const Any& rValue ) throw (IllegalArgumentException)
{
    sal_Bool bModified = sal_False;
    switch(nHandle)
    {
        case PROPERTY_ID_ALIGN:
        case PROPERTY_ID_NUMBERFORMAT:
        case PROPERTY_ID_RELATIVEPOSITION:
        case PROPERTY_ID_WIDTH:
        case PROPERTY_ID_HIDDEN:
        case PROPERTY_ID_CONTROLMODEL:
        case PROPERTY_ID_HELPTEXT:
        case PROPERTY_ID_CONTROLDEFAULT:
            bModified = OColumnSettings::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
            break;
        case PROPERTY_ID_VALUE:
            rConvertedValue = rValue;
            getFastPropertyValue(rOldValue, PROPERTY_ID_VALUE);
            bModified = !::comphelper::compare(rConvertedValue, rOldValue);
            break;
        default:
            bModified = ODataColumn::convertFastPropertyValue(rConvertedValue, rOldValue, nHandle, rValue);

    }

    return bModified;
}
//--------------------------------------------------------------------------
Sequence< sal_Int8 > ORowSetDataColumn::getImplementationId() throw (RuntimeException)
{
    static OImplementationId * pId = 0;
    if (! pId)
    {
        MutexGuard aGuard( Mutex::getGlobalMutex() );
        if (! pId)
        {
            static OImplementationId aId;
            pId = &aId;
        }
    }
    return pId->getImplementationId();
}
// -------------------------------------------------------------------------
void ORowSetDataColumn::fireValueChange(const ORowSetValue& _rOldValue)
{
    if(!m_aColumnValue.isNull() && m_aColumnValue != m_rEnd && m_aColumnValue->isValid() && (!((*(*m_aColumnValue))[m_nPos] == _rOldValue)))
    {
        sal_Int32 nHandle = PROPERTY_ID_VALUE;
        m_aOldValue = _rOldValue.makeAny();
        Any aNew = (*(*m_aColumnValue))[m_nPos].makeAny();

        fire(&nHandle, &aNew, &m_aOldValue, 1, sal_False );
    }
    else if ( !m_aColumnValue.isNull() && m_aColumnValue == m_rEnd && !_rOldValue.isNull() )
    {
        sal_Int32 nHandle = PROPERTY_ID_VALUE;
        m_aOldValue = _rOldValue.makeAny();
        Any aNew;

        fire(&nHandle, &aNew, &m_aOldValue, 1, sal_False );
    }
}
// -----------------------------------------------------------------------------
DBG_NAME(ORowSetDataColumns )
ORowSetDataColumns::ORowSetDataColumns(
                sal_Bool _bCase,
                const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,
                ::cppu::OWeakObject& _rParent,
                ::osl::Mutex& _rMutex,
                const ::std::vector< ::rtl::OUString> &_rVector
                ) : connectivity::sdbcx::OCollection(_rParent,_bCase,_rMutex,_rVector)
                ,m_aColumns(_rColumns)
{
    DBG_CTOR(ORowSetDataColumns ,NULL);
}
// -----------------------------------------------------------------------------
ORowSetDataColumns::~ORowSetDataColumns()
{
    DBG_DTOR(ORowSetDataColumns ,NULL);
}
// -----------------------------------------------------------------------------
sdbcx::ObjectType ORowSetDataColumns::createObject(const ::rtl::OUString& _rName)
{
    connectivity::sdbcx::ObjectType xNamed;

    ::comphelper::UStringMixEqual aCase(isCaseSensitive());
    ::connectivity::OSQLColumns::const_iterator first =  ::connectivity::find(m_aColumns->begin(),m_aColumns->end(),_rName,aCase);
    if(first != m_aColumns->end())
        xNamed.set(*first,UNO_QUERY);

    return xNamed;
}
// -----------------------------------------------------------------------------
void SAL_CALL ORowSetDataColumns::disposing(void)
{
    //  clear_NoDispose();
    ORowSetDataColumns_BASE::disposing();
    m_aColumns = NULL;
    //  m_aColumns.clear();
}
// -----------------------------------------------------------------------------
void ORowSetDataColumns::assign(const ::vos::ORef< ::connectivity::OSQLColumns>& _rColumns,const ::std::vector< ::rtl::OUString> &_rVector)
{
    m_aColumns = _rColumns;
    reFill(_rVector);
}
// -----------------------------------------------------------------------------
void ORowSetDataColumns::impl_refresh() throw(::com::sun::star::uno::RuntimeException)
{
}
// -----------------------------------------------------------------------------

<|endoftext|>


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

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

namespace dbaui
{
    class SAL_NO_VTABLE IAccessibleHelper
    {
    protected:
        /** isEditable returns the current editable state
            @return true if it is editable otherwise false
        */
        virtual sal_Bool isEditable() const = 0;
    public:
        /** notifies all listeners that this object has changed
            @param  _nEventId   the event id
            @param  _aOldValue  the old value
            @param  _aNewValue  the new value
        */
        virtual void notifyAccessibleEvent( sal_Int16 _nEventId,
                                            const ::com::sun::star::uno::Any& _aOldValue,
                                            const ::com::sun::star::uno::Any& _aNewValue) = 0;
    };
}
#endif // DBAUI_ACCESSIBLE_HELPER_IFACE_HXX
<commit_msg>INTEGRATION: CWS ooo19126 (1.2.482); FILE MERGED 2005/09/05 17:34:14 rt 1.2.482.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AccessibleBaseIFace.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 15:13:30 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBAUI_ACCESSIBLE_HELPER_IFACE_HXX
#define DBAUI_ACCESSIBLE_HELPER_IFACE_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

namespace dbaui
{
    class SAL_NO_VTABLE IAccessibleHelper
    {
    protected:
        /** isEditable returns the current editable state
            @return true if it is editable otherwise false
        */
        virtual sal_Bool isEditable() const = 0;
    public:
        /** notifies all listeners that this object has changed
            @param  _nEventId   the event id
            @param  _aOldValue  the old value
            @param  _aNewValue  the new value
        */
        virtual void notifyAccessibleEvent( sal_Int16 _nEventId,
                                            const ::com::sun::star::uno::Any& _aOldValue,
                                            const ::com::sun::star::uno::Any& _aNewValue) = 0;
    };
}
#endif // DBAUI_ACCESSIBLE_HELPER_IFACE_HXX
<|endoftext|>


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

#ifndef _DBAUI_DATASOURCECONNECTOR_HXX_
#define _DBAUI_DATASOURCECONNECTOR_HXX_

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
#include <com/sun/star/sdbc/XDataSource.hpp>
#endif

class Window;
//.........................................................................
namespace dbaui
{
//.........................................................................

    //=====================================================================
    //= ODatasourceConnector
    //=====================================================================
    class ODatasourceConnector
    {
    protected:
        Window*         m_pErrorMessageParent;
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                        m_xORB;
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
                        m_xDatabaseContext;
        ::rtl::OUString m_sContextInformation;
        ::rtl::OUString m_sContextDetails;

    public:
        ODatasourceConnector(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
            Window* _pMessageParent
        );
        ODatasourceConnector(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
            Window* _pMessageParent,
            const ::rtl::OUString& _rContextInformation,
            const ::rtl::OUString& _rContextDetails = ::rtl::OUString()
        );

        /// returns <TRUE/> if the object is able to create data source connections
        sal_Bool    isValid() const { return m_xDatabaseContext.is(); }

        /// create a data source connection
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
                    connect(const ::rtl::OUString& _rDataSourceName, sal_Bool _bShowError = sal_True) const;

        /// create a data source connection
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
                    connect(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource>& _xDataSource
                            , sal_Bool _bShowError = sal_True) const;

    private:
        void implConstruct();
    };

//.........................................................................
}   // namespace dbaui
//.........................................................................

#endif // _DBAUI_DATASOURCECONNECTOR_HXX_

<commit_msg>INTEGRATION: CWS dba23b (1.5.282); FILE MERGED 2007/07/08 20:34:47 fs 1.5.282.1: during #i65812#: context details not used<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: datasourceconnector.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2007-07-24 12:09:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _DBAUI_DATASOURCECONNECTOR_HXX_
#define _DBAUI_DATASOURCECONNECTOR_HXX_

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
#include <com/sun/star/sdbc/XDataSource.hpp>
#endif

class Window;
//.........................................................................
namespace dbaui
{
//.........................................................................

    //=====================================================================
    //= ODatasourceConnector
    //=====================================================================
    class ODatasourceConnector
    {
    protected:
        Window*         m_pErrorMessageParent;
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                        m_xORB;
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >
                        m_xDatabaseContext;
        ::rtl::OUString m_sContextInformation;

    public:
        ODatasourceConnector(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
            Window* _pMessageParent
        );
        ODatasourceConnector(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
            Window* _pMessageParent,
            const ::rtl::OUString& _rContextInformation
        );

        /// returns <TRUE/> if the object is able to create data source connections
        sal_Bool    isValid() const { return m_xDatabaseContext.is(); }

        /// create a data source connection
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
                    connect(const ::rtl::OUString& _rDataSourceName, sal_Bool _bShowError = sal_True) const;

        /// create a data source connection
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
                    connect(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDataSource>& _xDataSource
                            , sal_Bool _bShowError = sal_True) const;

    private:
        void implConstruct();
    };

//.........................................................................
}   // namespace dbaui
//.........................................................................

#endif // _DBAUI_DATASOURCECONNECTOR_HXX_

<|endoftext|>


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

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

#include <vector>
#include <string>

#include <memory>

#include "Nodes.hpp"
#include "Utils.hpp"

namespace eddic {

template<typename T>
std::string mangle(std::string functionName, std::vector<std::shared_ptr<T>> typed){
    if(functionName == "main"){
        return functionName;
    }

    std::ostringstream ss;

    ss << "_F";
    ss << functionName.length();
    ss << functionName;

    for(std::shared_ptr<T>& t : typed){
        ss << mangle(t->type());
    }

    return ss.str();
}

//TODO Remove this method once everything is passed by smart pointers
template<typename T>
std::string mangle(std::string functionName, std::vector<T*> typed){
    if(functionName == "main"){
        return functionName;
    }

    std::string ss;

    ss += "_F";
    ss += toString(functionName.length());
    ss += functionName;

    typename std::vector<T*>::const_iterator it = typed.begin();

    for( ; it != typed.end(); ++it){
        ss += mangle((*it)->type());
    }

    return ss;
}

std::string mangle(Type type);

class MainDeclaration : public ParseNode {
   public:
        MainDeclaration(Context* context) : ParseNode(context) {};

        void write(AssemblyFileWriter& writer);
};

class Parameter {
    private:
        std::string m_name;
        Type m_type;
        int m_offset;

    public:
        Parameter(const std::string& name, Type type, int offset) : m_name(name), m_type(type), m_offset(offset) {}

        Type type(){
            return m_type;
        }

        int offset(){
            return m_offset;
        }
};

class Function : public ParseNode {
	private:
		std::string m_name;
        std::vector<std::shared_ptr<Parameter>> m_parameters;
        int m_currentPosition;

	public:
		Function(Context* context, const Token* token, const std::string& name) : ParseNode(context, token), m_name(name), m_currentPosition(0) {}

        void write(AssemblyFileWriter& writer);

        std::string name(){
            return m_name;
        }

        std::string mangledName(){
            return mangle(m_name, m_parameters);
        }

        void addParameter(std::string name, Type type);
};

class FunctionCall : public ParseNode {
    private:
        std::string m_function;
        std::string m_function_mangled;
        std::vector<Value*> m_values;

    public:
        FunctionCall(Context* context, const Token* token, const std::string& function) : ParseNode(context, token), m_function(function) {}

        void write(AssemblyFileWriter& writer);
        void checkFunctions(Program& program);

        void addValue(Value* value){
            m_values.push_back(value);
            addLast(value);
        }
};

} //end of eddic

#endif
<commit_msg>Pass parameters by const reference<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

#include <vector>
#include <string>

#include <memory>

#include "Nodes.hpp"
#include "Utils.hpp"

namespace eddic {

template<typename T>
std::string mangle(const std::string& functionName, const std::vector<std::shared_ptr<T>>& typed){
    if(functionName == "main"){
        return functionName;
    }

    std::ostringstream ss;

    ss << "_F";
    ss << functionName.length();
    ss << functionName;

    for(const std::shared_ptr<T>& t : typed){
        ss << mangle(t->type());
    }

    return ss.str();
}

//TODO Remove this method once everything is passed by smart pointers
template<typename T>
std::string mangle(std::string functionName, std::vector<T*> typed){
    if(functionName == "main"){
        return functionName;
    }

    std::string ss;

    ss += "_F";
    ss += toString(functionName.length());
    ss += functionName;

    typename std::vector<T*>::const_iterator it = typed.begin();

    for( ; it != typed.end(); ++it){
        ss += mangle((*it)->type());
    }

    return ss;
}

std::string mangle(Type type);

class MainDeclaration : public ParseNode {
   public:
        MainDeclaration(Context* context) : ParseNode(context) {};

        void write(AssemblyFileWriter& writer);
};

class Parameter {
    private:
        std::string m_name;
        Type m_type;
        int m_offset;

    public:
        Parameter(const std::string& name, Type type, int offset) : m_name(name), m_type(type), m_offset(offset) {}

        Type type(){
            return m_type;
        }

        int offset(){
            return m_offset;
        }
};

class Function : public ParseNode {
	private:
		std::string m_name;
        std::vector<std::shared_ptr<Parameter>> m_parameters;
        int m_currentPosition;

	public:
		Function(Context* context, const Token* token, const std::string& name) : ParseNode(context, token), m_name(name), m_currentPosition(0) {}

        void write(AssemblyFileWriter& writer);

        std::string name(){
            return m_name;
        }

        std::string mangledName(){
            return mangle(m_name, m_parameters);
        }

        void addParameter(std::string name, Type type);
};

class FunctionCall : public ParseNode {
    private:
        std::string m_function;
        std::string m_function_mangled;
        std::vector<Value*> m_values;

    public:
        FunctionCall(Context* context, const Token* token, const std::string& function) : ParseNode(context, token), m_function(function) {}

        void write(AssemblyFileWriter& writer);
        void checkFunctions(Program& program);

        void addValue(Value* value){
            m_values.push_back(value);
            addLast(value);
        }
};

} //end of eddic

#endif
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <sensor_msgs/Imu.h>
#include <nav_msgs/Odometry.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <tf/transform_broadcaster.h>
#include <tf/transform_listener.h>
#include <memory>
#include <iostream>

using namespace tf;
using namespace std;

ros::Publisher pose_pub;
ros::Publisher origin_pub;
std::unique_ptr<TransformBroadcaster> tf_broadcaster;
std::unique_ptr<TransformListener> tf_listener;

geometry_msgs::Quaternion orientation;
nav_msgs::Odometry gps;

geometry_msgs::Point origin;
bool first = true;

bool orientationIsValid()
{
    return orientation.w != 0 ||
           orientation.x != 0 ||
           orientation.y != 0 ||
           orientation.z != 0;
}

void publish_pose()
{
    if(!orientationIsValid())
        return;
    geometry_msgs::PoseStamped pose;
    pose.header.frame_id = "/map";
    pose.pose.position.x = gps.pose.pose.position.x;
    pose.pose.position.y = gps.pose.pose.position.y;
    pose.pose.position.z = 0.0;
    pose.pose.orientation = orientation;
    pose_pub.publish(pose);

    Transform transform;
    transform.setOrigin(Vector3(pose.pose.position.x, pose.pose.position.y, 0.0));
    Quaternion q;
    quaternionMsgToTF(pose.pose.orientation, q);
    transform.setRotation(q);
    tf_broadcaster->sendTransform(StampedTransform(transform, ros::Time::now(), "map", "base_footprint"));
}

void imu_callback(const sensor_msgs::ImuConstPtr& msg)
{
    geometry_msgs::QuaternionStamped q;
    q.header.stamp = ros::Time(0);
    q.header.frame_id = msg->header.frame_id;
    q.quaternion = msg->orientation;
    tf_listener->waitForTransform("base_footprint", msg->header.frame_id, ros::Time(0), ros::Duration(10.0));
    geometry_msgs::QuaternionStamped transformed;
    tf_listener->transformQuaternion("base_footprint", q, transformed);
    orientation = msg->orientation;//transformed.quaternion;
}

void gps_callback(const nav_msgs::OdometryConstPtr& msg)
{
    gps = *msg;

    tf_listener->waitForTransform("base_footprint", msg->header.frame_id, ros::Time(0), ros::Duration(10.0));
    geometry_msgs::PoseStamped p;
    p.header.stamp = ros::Time(0);
    p.header.frame_id = msg->header.frame_id;
    p.pose = msg->pose.pose;
    geometry_msgs::PoseStamped transformed;
    tf_listener->transformPose("base_footprint", p, transformed);
    gps.pose.pose = transformed.pose;

    if(first)
    {
        origin = gps.pose.pose.position;
        first = false;
    } else {
        gps.pose.pose.position.x -= origin.x;
        gps.pose.pose.position.y -= origin.y;
        gps.pose.pose.position.z -= origin.z;
    }
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "pose_tracker");

    tf_broadcaster = std::unique_ptr<TransformBroadcaster>(new TransformBroadcaster);

    tf_listener = std::unique_ptr<TransformListener>(new TransformListener);

    ros::NodeHandle nh;

    ros::Subscriber imu_sub = nh.subscribe("/imu", 1, imu_callback);

    ros::Subscriber gps_sub = nh.subscribe("/gps_odom", 1, gps_callback);

    pose_pub = nh.advertise<geometry_msgs::PoseStamped>("/odom_combined", 1);

    origin_pub = nh.advertise<geometry_msgs::PointStamped>("/map_origin", 1);

    // Publish initial pose
    orientation.x = 0;
    orientation.y = 0;
    orientation.z = 1;
    orientation.w = 0;
    publish_pose();

    ros::Rate rate(20); // 20 Hz
    while(ros::ok())
    {
        ros::spinOnce();

        geometry_msgs::PointStamped msg;
        msg.header.stamp = ros::Time::now();
        msg.header.frame_id = "/world";
        msg.point = origin;
        origin_pub.publish(msg);

        publish_pose();

        rate.sleep();
    }

    return 0;
}
<commit_msg>Cleaning up pose_tracker a bit.<commit_after>#include <ros/ros.h>
#include <sensor_msgs/Imu.h>
#include <nav_msgs/Odometry.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <tf/transform_broadcaster.h>
#include <tf/transform_listener.h>
#include <memory>
#include <iostream>

using namespace tf;
using namespace std;

ros::Publisher pose_pub;
ros::Publisher origin_pub;
std::unique_ptr<TransformBroadcaster> tf_broadcaster;
std::unique_ptr<TransformListener> tf_listener;

geometry_msgs::Quaternion orientation;
nav_msgs::Odometry gps;

geometry_msgs::Point origin;
bool first = true;

bool orientationIsValid()
{
    return orientation.w != 0 ||
           orientation.x != 0 ||
           orientation.y != 0 ||
           orientation.z != 0;
}

void publish_pose()
{
    if(!orientationIsValid())
        return;
    geometry_msgs::PoseStamped pose;
    pose.header.frame_id = "/map";
    pose.pose.position.x = gps.pose.pose.position.x;
    pose.pose.position.y = gps.pose.pose.position.y;
    pose.pose.position.z = 0.0;
    pose.pose.orientation = orientation;
    pose_pub.publish(pose);

    Transform transform;
    transform.setOrigin(Vector3(pose.pose.position.x, pose.pose.position.y, 0.0));
    Quaternion q;
    quaternionMsgToTF(orientation, q);
    transform.setRotation(q);
    tf_broadcaster->sendTransform(StampedTransform(transform, ros::Time::now(), "map", "base_footprint"));
}

void imu_callback(const sensor_msgs::ImuConstPtr& msg)
{
//    geometry_msgs::QuaternionStamped q;
//    q.header.stamp = ros::Time(0);
//    q.header.frame_id = msg->header.frame_id;
//    q.quaternion = msg->orientation;
//    tf_listener->waitForTransform("base_footprint", msg->header.frame_id, ros::Time(0), ros::Duration(10.0));
//    geometry_msgs::QuaternionStamped transformed;
//    tf_listener->transformQuaternion("base_footprint", q, transformed);
    orientation = msg->orientation;//transformed.quaternion;
}

void gps_callback(const nav_msgs::OdometryConstPtr& msg)
{
    gps = *msg;

    tf_listener->waitForTransform("base_footprint", msg->header.frame_id, ros::Time(0), ros::Duration(10.0));
    geometry_msgs::PoseStamped p;
    p.header.stamp = ros::Time(0);
    p.header.frame_id = msg->header.frame_id;
    p.pose = msg->pose.pose;
    geometry_msgs::PoseStamped transformed;
    tf_listener->transformPose("base_footprint", p, transformed);
    gps.pose.pose = transformed.pose;

    if(first)
    {
        origin = gps.pose.pose.position;
        first = false;
    } else {
        gps.pose.pose.position.x -= origin.x;
        gps.pose.pose.position.y -= origin.y;
        gps.pose.pose.position.z -= origin.z;
    }
}

int main(int argc, char** argv)
{
    ros::init(argc, argv, "pose_tracker");

    tf_broadcaster = std::unique_ptr<TransformBroadcaster>(new TransformBroadcaster);

    tf_listener = std::unique_ptr<TransformListener>(new TransformListener);

    ros::NodeHandle nh;

    ros::Subscriber imu_sub = nh.subscribe("/imu", 1, imu_callback);

    ros::Subscriber gps_sub = nh.subscribe("/gps_odom", 1, gps_callback);

    pose_pub = nh.advertise<geometry_msgs::PoseStamped>("/odom_combined", 1);

    origin_pub = nh.advertise<geometry_msgs::PointStamped>("/map_origin", 1);

    // Publish initial pose
    orientation.x = 0;
    orientation.y = 0;
    orientation.z = 1;
    orientation.w = 0;
    publish_pose();

    ros::Rate rate(20); // 20 Hz
    while(ros::ok())
    {
        ros::spinOnce();

        geometry_msgs::PointStamped msg;
        msg.header.stamp = ros::Time::now();
        msg.header.frame_id = "/world";
        msg.point = origin;
        origin_pub.publish(msg);

        publish_pose();

        rate.sleep();
    }

    return 0;
}
<|endoftext|>


<commit_before>// Copyright 2014 BVLC and contributors.

#include <cmath>
#include <cstring>
#include <vector>

#include "cuda_runtime.h"
#include "gtest/gtest.h"
#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/filler.hpp"
#include "caffe/vision_layers.hpp"
#include "caffe/test/test_gradient_check_util.hpp"

#include "caffe/test/test_caffe_main.hpp"

namespace caffe {

extern cudaDeviceProp CAFFE_TEST_CUDA_PROP;

template <typename Dtype>
class SoftmaxLayerTest : public ::testing::Test {
 protected:
  SoftmaxLayerTest()
      : blob_bottom_(new Blob<Dtype>(2, 10, 1, 1)),
        blob_top_(new Blob<Dtype>()) {
    // fill the values
    FillerParameter filler_param;
    GaussianFiller<Dtype> filler(filler_param);
    filler.Fill(this->blob_bottom_);
    blob_bottom_vec_.push_back(blob_bottom_);
    blob_top_vec_.push_back(blob_top_);
  }
  virtual ~SoftmaxLayerTest() { delete blob_bottom_; delete blob_top_; }
  Blob<Dtype>* const blob_bottom_;
  Blob<Dtype>* const blob_top_;
  vector<Blob<Dtype>*> blob_bottom_vec_;
  vector<Blob<Dtype>*> blob_top_vec_;
};

TYPED_TEST_CASE(SoftmaxLayerTest, TestDtypes);

TYPED_TEST(SoftmaxLayerTest, TestForward) {
  LayerParameter layer_param;
  SoftmaxLayer<TypeParam> layer(layer_param);
  layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  layer.Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
  // Test sum
  for (int i = 0; i < this->blob_bottom_->num(); ++i) {
    TypeParam sum = 0;
    for (int j = 0; j < this->blob_top_->channels(); ++j) {
      sum += this->blob_top_->data_at(i, j, 0, 0);
    }
    EXPECT_GE(sum, 0.999);
    EXPECT_LE(sum, 1.001);
  }
  // Test exact values
  for (int i = 0; i < this->blob_bottom_->num(); ++i) {
    TypeParam scale = 0;
    for (int j = 0; j < this->blob_bottom_->channels(); ++j) {
      scale += exp(this->blob_bottom_->data_at(i, j, 0, 0));
    }
    for (int j = 0; j < this->blob_bottom_->channels(); ++j) {
      EXPECT_GE(this->blob_top_->data_at(i, j, 0, 0) + 1e-4,
          exp(this->blob_bottom_->data_at(i, j, 0, 0)) / scale)
          << "debug: " << i << " " << j;
      EXPECT_LE(this->blob_top_->data_at(i, j, 0, 0) - 1e-4,
          exp(this->blob_bottom_->data_at(i, j, 0, 0)) / scale)
          << "debug: " << i << " " << j;
    }
  }
}

TYPED_TEST(SoftmaxLayerTest, TestGradient) {
  LayerParameter layer_param;
  SoftmaxLayer<TypeParam> layer(layer_param);
  GradientChecker<TypeParam> checker(1e-2, 1e-3);
  checker.CheckGradientExhaustive(&layer, &(this->blob_bottom_vec_),
      &(this->blob_top_vec_));
}

}  // namespace caffe
<commit_msg>Fix SoftmaxLayerTest: forgot to change this one to use DtypesAndDevices; was causing Travis build to randomly fail if a previous test had set the mode to GPU (which no test that is run by 'make runtestnogpu' should, so I guess there's another bug somewhere).<commit_after>// Copyright 2014 BVLC and contributors.

#include <cmath>
#include <cstring>
#include <vector>

#include "cuda_runtime.h"
#include "gtest/gtest.h"
#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/filler.hpp"
#include "caffe/vision_layers.hpp"
#include "caffe/test/test_gradient_check_util.hpp"

#include "caffe/test/test_caffe_main.hpp"

namespace caffe {

extern cudaDeviceProp CAFFE_TEST_CUDA_PROP;

template <typename TypeParam>
class SoftmaxLayerTest : public MultiDeviceTest<TypeParam> {
  typedef typename TypeParam::Dtype Dtype;
 protected:
  SoftmaxLayerTest()
      : blob_bottom_(new Blob<Dtype>(2, 10, 1, 1)),
        blob_top_(new Blob<Dtype>()) {
    // fill the values
    FillerParameter filler_param;
    GaussianFiller<Dtype> filler(filler_param);
    filler.Fill(this->blob_bottom_);
    blob_bottom_vec_.push_back(blob_bottom_);
    blob_top_vec_.push_back(blob_top_);
  }
  virtual ~SoftmaxLayerTest() { delete blob_bottom_; delete blob_top_; }
  Blob<Dtype>* const blob_bottom_;
  Blob<Dtype>* const blob_top_;
  vector<Blob<Dtype>*> blob_bottom_vec_;
  vector<Blob<Dtype>*> blob_top_vec_;
};

TYPED_TEST_CASE(SoftmaxLayerTest, TestDtypesAndDevices);

TYPED_TEST(SoftmaxLayerTest, TestForward) {
  typedef typename TypeParam::Dtype Dtype;
  LayerParameter layer_param;
  SoftmaxLayer<Dtype> layer(layer_param);
  layer.SetUp(this->blob_bottom_vec_, &(this->blob_top_vec_));
  layer.Forward(this->blob_bottom_vec_, &(this->blob_top_vec_));
  // Test sum
  for (int i = 0; i < this->blob_bottom_->num(); ++i) {
    Dtype sum = 0;
    for (int j = 0; j < this->blob_top_->channels(); ++j) {
      sum += this->blob_top_->data_at(i, j, 0, 0);
    }
    EXPECT_GE(sum, 0.999);
    EXPECT_LE(sum, 1.001);
  }
  // Test exact values
  for (int i = 0; i < this->blob_bottom_->num(); ++i) {
    Dtype scale = 0;
    for (int j = 0; j < this->blob_bottom_->channels(); ++j) {
      scale += exp(this->blob_bottom_->data_at(i, j, 0, 0));
    }
    for (int j = 0; j < this->blob_bottom_->channels(); ++j) {
      EXPECT_GE(this->blob_top_->data_at(i, j, 0, 0) + 1e-4,
          exp(this->blob_bottom_->data_at(i, j, 0, 0)) / scale)
          << "debug: " << i << " " << j;
      EXPECT_LE(this->blob_top_->data_at(i, j, 0, 0) - 1e-4,
          exp(this->blob_bottom_->data_at(i, j, 0, 0)) / scale)
          << "debug: " << i << " " << j;
    }
  }
}

TYPED_TEST(SoftmaxLayerTest, TestGradient) {
  typedef typename TypeParam::Dtype Dtype;
  LayerParameter layer_param;
  SoftmaxLayer<Dtype> layer(layer_param);
  GradientChecker<Dtype> checker(1e-2, 1e-3);
  checker.CheckGradientExhaustive(&layer, &(this->blob_bottom_vec_),
      &(this->blob_top_vec_));
}

}  // namespace caffe
<|endoftext|>


<commit_before>// Copyright (c) 2020 by Apex.AI Inc. All rights reserved.
//
// 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.

#ifndef IOX_POSH_POPO_TRIGGER_STATE_HPP
#define IOX_POSH_POPO_TRIGGER_STATE_HPP

#include "iceoryx_posh/internal/log/posh_logging.hpp"
#include "iceoryx_utils/cxx/function_ref.hpp"

#include <cstdint>
#include <limits>

namespace iox
{
namespace popo
{
class TriggerState
{
  public:
    static constexpr uint64_t INVALID_TRIGGER_ID = std::numeric_limits<uint64_t>::max();
    template <typename T>
    using Callback = void (*)(T* const);

    TriggerState() = default;

    template <typename T>
    TriggerState(T* const origin, const uint64_t triggerId, const Callback<T> callback) noexcept;

    uint64_t getTriggerId() const noexcept;

    template <typename T>
    bool doesOriginateFrom(T* const origin) const noexcept;

    template <typename T>
    T* getOrigin() noexcept;

    template <typename T>
    const T* getOrigin() const noexcept;

    bool operator()() const noexcept;

  protected:
    void* m_origin = nullptr;
    uint64_t m_originTypeHash = 0U;
    uint64_t m_triggerId = INVALID_TRIGGER_ID;

    Callback<void> m_callbackPtr;
    cxx::function_ref<void(void* const, Callback<void>)> m_callback;
};

} // namespace popo
} // namespace iox

#include "iceoryx_posh/internal/popo/trigger_state.inl"

#endif
<commit_msg>iox-#341 documented trigger state<commit_after>// Copyright (c) 2020 by Apex.AI Inc. All rights reserved.
//
// 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.

#ifndef IOX_POSH_POPO_TRIGGER_STATE_HPP
#define IOX_POSH_POPO_TRIGGER_STATE_HPP

#include "iceoryx_posh/internal/log/posh_logging.hpp"
#include "iceoryx_utils/cxx/function_ref.hpp"

#include <cstdint>
#include <limits>

namespace iox
{
namespace popo
{
/// @brief TriggerState holds the state of a trigger and is the base class
///        for trigger.
class TriggerState
{
  public:
    static constexpr uint64_t INVALID_TRIGGER_ID = std::numeric_limits<uint64_t>::max();
    template <typename T>
    using Callback = void (*)(T* const);

    /// @brief constructs an empty TriggerState
    TriggerState() = default;

    /// @brief constructs a TriggerState object
    /// @param[in] origin pointer to the origin of the TriggerState
    /// @param[in] triggerId id of the trigger
    /// @param[in] callback the callback of the trigger
    template <typename T>
    TriggerState(T* const origin, const uint64_t triggerId, const Callback<T> callback) noexcept;

    /// @brief returns the trigger id
    /// @return the empty TriggerState always returns INVALID_TRIGGER_ID, otherwise the actual triggerId is returned
    /// which can also be INVALID_TRIGGER_ID
    uint64_t getTriggerId() const noexcept;

    /// @brief confirms the origin
    /// @param[in] origin the possible origin
    /// @return true if the address is equal to the origin, otherwise false. The empty TriggerState returns always
    /// false.
    template <typename T>
    bool doesOriginateFrom(T* const origin) const noexcept;

    /// @brief returns the pointer to the origin.
    /// @return If T equals the origin type and the TriggerState is not empty it returns the pointer to the origin.
    /// Otherwise it returns nullptr. If the type is wrong it prints an additional FATAL error message.
    template <typename T>
    T* getOrigin() noexcept;

    /// @brief returns the pointer to the origin.
    /// @return If T equals the origin type and the TriggerState is not empty it returns the pointer to the origin.
    /// Otherwise it returns nullptr. If the type is wrong it prints an additional FATAL error message.
    template <typename T>
    const T* getOrigin() const noexcept;

    /// @brief If a callback is set it executes the callback.
    /// @return true if the callback was called, otherwise false
    bool operator()() const noexcept;

  protected:
    void* m_origin = nullptr;
    uint64_t m_originTypeHash = 0U;
    uint64_t m_triggerId = INVALID_TRIGGER_ID;

    Callback<void> m_callbackPtr = nullptr;
    cxx::function_ref<void(void* const, Callback<void>)> m_callback;
};

} // namespace popo
} // namespace iox

#include "iceoryx_posh/internal/popo/trigger_state.inl"

#endif
<|endoftext|>


<commit_before>#include "Runtime/MP1/World/CEyeball.hpp"

#include "Runtime/CStateManager.hpp"
#include "Runtime/Weapon/CBeamInfo.hpp"
#include "Runtime/Weapon/CGameProjectile.hpp"
#include "Runtime/Weapon/CPlasmaProjectile.hpp"
#include "Runtime/World/CGameArea.hpp"
#include "Runtime/World/CPlayer.hpp"
#include "Runtime/World/CWorld.hpp"

#include "TCastTo.hpp" // Generated file, do not modify include path

namespace urde::MP1 {
CEyeball::CEyeball(TUniqueId uid, std::string_view name, CPatterned::EFlavorType flavor, const CEntityInfo& info,
                   const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, float attackDelay,
                   float attackStartTime, CAssetId wpscId, const CDamageInfo& dInfo, CAssetId beamContactFxId,
                   CAssetId beamPulseFxId, CAssetId beamTextureId, CAssetId beamGlowTextureId, u32 anim0, u32 anim1,
                   u32 anim2, u32 anim3, u32 beamSfx, bool attackDisabled, const CActorParameters& actParms)
: CPatterned(ECharacter::EyeBall, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
             EColliderType::Zero, EBodyType::Restricted, actParms, EKnockBackVariant::Medium)
, x568_attackDelay(attackDelay)
, x56c_attackStartTime(attackStartTime)
, x570_boneTracking(*GetModelData()->GetAnimationData(), "Eye"sv, zeus::degToRad(45.f), zeus::degToRad(180.f),
                    EBoneTrackingFlags::NoParent)
, x5b4_projectileInfo(wpscId, dInfo)
, x5dc_beamContactFxId(beamContactFxId)
, x5e0_beamPulseFxId(beamPulseFxId)
, x5e4_beamTextureId(beamTextureId)
, x5e8_beamGlowTextureId(beamGlowTextureId)
, x604_beamSfxId(CSfxManager::TranslateSFXID(beamSfx))
, x60c_24_canAttack(false)
, x60c_25_playerInRange(false)
, x60c_26_alert(false)
, x60c_27_attackDisabled(attackDisabled)
, x60c_28_firingBeam(false) {
  x5f4_animIdxs[0] = anim0;
  x5f4_animIdxs[1] = anim1;
  x5f4_animIdxs[2] = anim2;
  x5f4_animIdxs[3] = anim3;

  x460_knockBackController.SetAutoResetImpulse(false);
}

void CEyeball::Accept(IVisitor& visitor) { visitor.Visit(this); }

void CEyeball::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
  switch (msg) {
  case EScriptObjectMessage::ProjectileCollide:
  case EScriptObjectMessage::InvulnDamage: {
    if (TCastToConstPtr<CGameProjectile> proj = mgr.GetObjectById(uid)) {
      if (proj->GetOwnerId() == mgr.GetPlayer().GetUniqueId())
        if (GetDamageVulnerability()->GetVulnerability(proj->GetDamageInfo().GetWeaponMode(), false) !=
            EVulnerability::Deflect)
          x400_24_hitByPlayerProjectile = true;
    }
    return;
  }
  case EScriptObjectMessage::Alert:
    x60c_26_alert = true;
    break;
  case EScriptObjectMessage::Registered: {
    RemoveMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr);
    x450_bodyController->Activate(mgr);
    x330_stateMachineState.SetDelay(0.f);
    CreateShadow(false);
    CreateBeam(mgr);
    break;
  }
  case EScriptObjectMessage::Deleted: {
    if (x5ec_projectileId != kInvalidUniqueId) {
      mgr.FreeScriptObject(x5ec_projectileId);
      if (x608_beamSfx) {
        CSfxManager::RemoveEmitter(x608_beamSfx);
        x608_beamSfx.reset();
      }
    }
    x5ec_projectileId = kInvalidUniqueId;
    break;
  }
  default:
    break;
  }
  CPatterned::AcceptScriptMsg(msg, uid, mgr);
}

void CEyeball::Think(float dt, CStateManager& mgr) {
  CPatterned::Think(dt, mgr);

  if (!GetActive()) {
    return;
  }

  const CPlayer& player = mgr.GetPlayer();
  const zeus::CVector3f direction = (player.GetTranslation() - GetTranslation()).normalized();

  // Used to be directly calculated as std::cos(zeus::degToRad(45.f));
  // but was converted into the exact constant to avoid unnecessary runtime initialization.
  constexpr float minAngle = 0.707106769f;

  x60c_25_playerInRange = (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed &&
                           direction.dot(GetTransform().frontVector()) > minAngle);

  if (x60c_25_playerInRange) {
    x570_boneTracking.SetActive(true);
    x5a8_targetPosition = player.GetTranslation() - (0.5f * player.GetVelocity());
    x570_boneTracking.SetTargetPosition(x5a8_targetPosition);
    x570_boneTracking.Update(dt);
    GetModelData()->GetAnimationData()->PreRender();
    x570_boneTracking.PreRender(mgr, *GetModelData()->GetAnimationData(), GetTransform(), GetModelData()->GetScale(),
                                *x450_bodyController.get());
  } else
    x570_boneTracking.SetActive(false);

  if (GetActive()) {
    CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId));
    if (projectile && projectile->GetActive())
      projectile->UpdateFx(GetLctrTransform(skEyeLocator), dt, mgr);
  }

  if (x60c_28_firingBeam) {
    const CGameArea* area = mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways());
    if (area->GetActive() && area->IsPostConstructed() &&
        area->GetPostConstructed()->x10dc_occlusionState == CGameArea::EOcclusionState::Occluded)
      ResetBeamState(mgr);
  }
}

void CEyeball::CreateBeam(CStateManager& mgr) {
  if (x5ec_projectileId != kInvalidUniqueId)
    return;

  CBeamInfo beamInfo(3, x5dc_beamContactFxId, x5e0_beamPulseFxId, x5e4_beamTextureId, x5e8_beamGlowTextureId, 50, 0.05f,
                     1.f, 2.f, 20.f, 1.f, 1.f, 2.f, zeus::CColor(1.f, 1.f, 1.f, 0.f), zeus::CColor(0.f, 1.f, 0.5f, 0.f),
                     150.f);
  x5ec_projectileId = mgr.AllocateUniqueId();
  mgr.AddObject(new CPlasmaProjectile(x5b4_projectileInfo.Token(), "EyeBall_Beam"sv, EWeaponType::AI, beamInfo,
                                      zeus::CTransform(), EMaterialTypes::Immovable,
                                      x5b4_projectileInfo.GetDamage(), x5ec_projectileId, GetAreaIdAlways(),
                                      GetUniqueId(), {}, false, EProjectileAttrib::KeepInCinematic));
}

void CEyeball::InActive(CStateManager&, EStateMsg msg, float) {
  if (msg == EStateMsg::Activate)
    x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
}

void CEyeball::Cover(CStateManager&, EStateMsg msg, float) {
  if (msg == EStateMsg::Activate) {
    x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
    x60c_24_canAttack = false;
    x330_stateMachineState.SetDelay(x568_attackDelay);
  }
}

void CEyeball::Flinch(CStateManager& mgr, EStateMsg msg, float arg) {
  if (msg == EStateMsg::Activate) {
    x32c_animState = EAnimState::Ready;
    x330_stateMachineState.SetDelay(x568_attackDelay);
  } else if (msg == EStateMsg::Update)
    TryCommand(mgr, pas::EAnimationState::KnockBack, CPatternedTryFunc(&CEyeball::TryFlinch), 0);
  else if (msg == EStateMsg::Deactivate)
    x32c_animState = EAnimState::NotReady;
}

void CEyeball::TryFlinch(CStateManager&, int arg) {
  x450_bodyController->GetCommandMgr().DeliverCmd(CBCKnockBackCmd(GetTransform().basis[0], pas::ESeverity(arg)));
}

void CEyeball::Active(CStateManager& mgr, EStateMsg msg, float) {
  if (msg == EStateMsg::Activate) {
    x400_24_hitByPlayerProjectile = 0;
    x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat);
    x60c_24_canAttack = false;
  } else if (msg == EStateMsg::Update) {
    if (x330_stateMachineState.GetTime() > x56c_attackStartTime)
      x60c_24_canAttack = true;

    UpdateAnimation();
  } else if (msg == EStateMsg::Deactivate) {
    x330_stateMachineState.SetDelay(x568_attackDelay);
    if (CPlasmaProjectile* proj = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId)))
      proj->ResetBeam(mgr, true);

    x60c_24_canAttack = false;

    CSfxManager::RemoveEmitter(x608_beamSfx);
    x608_beamSfx.reset();
  }
}

void CEyeball::UpdateAnimation() {
  if (std::fabs(GetModelData()->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) - 0.f) >= 0.00001f)
    return;

  x5f0_currentAnim = (x5f0_currentAnim + 1) & 3;
  for (u32 i = 0; i < 4; ++i) {
    if (x5f4_animIdxs[x5f0_currentAnim] != -1)
      break;

    x5f0_currentAnim = (x5f0_currentAnim + 1) & 3;
  }
  s32 animIdx = x5f4_animIdxs[x5f0_currentAnim];
  if (animIdx != -1)
    x450_bodyController->GetCommandMgr().DeliverCmd(CBCScriptedCmd(animIdx, false, false, 0.f));
}

void CEyeball::ResetBeamState(CStateManager& mgr) {
  if (CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId)))
    projectile->ResetBeam(mgr, true);

  x60c_28_firingBeam = false;
  if (x608_beamSfx) {
    CSfxManager::RemoveEmitter(x608_beamSfx);
    x608_beamSfx.reset();
  }
}

void CEyeball::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) {
  if (type == EUserEventType::DamageOff)
    ResetBeamState(mgr);
  else if (type == EUserEventType::DamageOn && x60c_24_canAttack)
    FireBeam(mgr, GetLctrTransform(node.GetLocatorName()));
  else
    CPatterned::DoUserAnimEvent(mgr, node, type, dt);
}

void CEyeball::FireBeam(CStateManager& mgr, const zeus::CTransform& xf) {
  if (CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId))) {
    if (!projectile->GetActive()) {
      projectile->Fire(xf, mgr, false);
      x60c_28_firingBeam = true;
      if (!x608_beamSfx) {
        CAudioSys::C3DEmitterParmData parmData{
            GetTranslation(), {}, 50.f, 0.1f, 0x1, x604_beamSfxId, 1.f /* 127 */, 0.15f /* 20 / 127 */, false, 127};
        x608_beamSfx = CSfxManager::AddEmitter(parmData, true, 127, true, GetAreaIdAlways());
      }
    }
  }
}

void CEyeball::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) {
  CPatterned::PreRender(mgr, frustum);
  x570_boneTracking.PreRender(mgr, *GetModelData()->GetAnimationData(), GetTransform(), GetModelData()->GetScale(),
                              *x450_bodyController);
}

void CEyeball::Death(CStateManager& mgr, const zeus::CVector3f& pos, EScriptObjectState state) {
  zeus::CTransform oldXf = GetTransform();
  CPatterned::Death(mgr, pos, state);
  SetTransform(oldXf);
}
} // namespace urde::MP1<commit_msg>CEyeball: Remove unnecessary .get() call<commit_after>#include "Runtime/MP1/World/CEyeball.hpp"

#include "Runtime/CStateManager.hpp"
#include "Runtime/Weapon/CBeamInfo.hpp"
#include "Runtime/Weapon/CGameProjectile.hpp"
#include "Runtime/Weapon/CPlasmaProjectile.hpp"
#include "Runtime/World/CGameArea.hpp"
#include "Runtime/World/CPlayer.hpp"
#include "Runtime/World/CWorld.hpp"

#include "TCastTo.hpp" // Generated file, do not modify include path

namespace urde::MP1 {
CEyeball::CEyeball(TUniqueId uid, std::string_view name, CPatterned::EFlavorType flavor, const CEntityInfo& info,
                   const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, float attackDelay,
                   float attackStartTime, CAssetId wpscId, const CDamageInfo& dInfo, CAssetId beamContactFxId,
                   CAssetId beamPulseFxId, CAssetId beamTextureId, CAssetId beamGlowTextureId, u32 anim0, u32 anim1,
                   u32 anim2, u32 anim3, u32 beamSfx, bool attackDisabled, const CActorParameters& actParms)
: CPatterned(ECharacter::EyeBall, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
             EColliderType::Zero, EBodyType::Restricted, actParms, EKnockBackVariant::Medium)
, x568_attackDelay(attackDelay)
, x56c_attackStartTime(attackStartTime)
, x570_boneTracking(*GetModelData()->GetAnimationData(), "Eye"sv, zeus::degToRad(45.f), zeus::degToRad(180.f),
                    EBoneTrackingFlags::NoParent)
, x5b4_projectileInfo(wpscId, dInfo)
, x5dc_beamContactFxId(beamContactFxId)
, x5e0_beamPulseFxId(beamPulseFxId)
, x5e4_beamTextureId(beamTextureId)
, x5e8_beamGlowTextureId(beamGlowTextureId)
, x604_beamSfxId(CSfxManager::TranslateSFXID(beamSfx))
, x60c_24_canAttack(false)
, x60c_25_playerInRange(false)
, x60c_26_alert(false)
, x60c_27_attackDisabled(attackDisabled)
, x60c_28_firingBeam(false) {
  x5f4_animIdxs[0] = anim0;
  x5f4_animIdxs[1] = anim1;
  x5f4_animIdxs[2] = anim2;
  x5f4_animIdxs[3] = anim3;

  x460_knockBackController.SetAutoResetImpulse(false);
}

void CEyeball::Accept(IVisitor& visitor) { visitor.Visit(this); }

void CEyeball::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
  switch (msg) {
  case EScriptObjectMessage::ProjectileCollide:
  case EScriptObjectMessage::InvulnDamage: {
    if (TCastToConstPtr<CGameProjectile> proj = mgr.GetObjectById(uid)) {
      if (proj->GetOwnerId() == mgr.GetPlayer().GetUniqueId())
        if (GetDamageVulnerability()->GetVulnerability(proj->GetDamageInfo().GetWeaponMode(), false) !=
            EVulnerability::Deflect)
          x400_24_hitByPlayerProjectile = true;
    }
    return;
  }
  case EScriptObjectMessage::Alert:
    x60c_26_alert = true;
    break;
  case EScriptObjectMessage::Registered: {
    RemoveMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr);
    x450_bodyController->Activate(mgr);
    x330_stateMachineState.SetDelay(0.f);
    CreateShadow(false);
    CreateBeam(mgr);
    break;
  }
  case EScriptObjectMessage::Deleted: {
    if (x5ec_projectileId != kInvalidUniqueId) {
      mgr.FreeScriptObject(x5ec_projectileId);
      if (x608_beamSfx) {
        CSfxManager::RemoveEmitter(x608_beamSfx);
        x608_beamSfx.reset();
      }
    }
    x5ec_projectileId = kInvalidUniqueId;
    break;
  }
  default:
    break;
  }
  CPatterned::AcceptScriptMsg(msg, uid, mgr);
}

void CEyeball::Think(float dt, CStateManager& mgr) {
  CPatterned::Think(dt, mgr);

  if (!GetActive()) {
    return;
  }

  const CPlayer& player = mgr.GetPlayer();
  const zeus::CVector3f direction = (player.GetTranslation() - GetTranslation()).normalized();

  // Used to be directly calculated as std::cos(zeus::degToRad(45.f));
  // but was converted into the exact constant to avoid unnecessary runtime initialization.
  constexpr float minAngle = 0.707106769f;

  x60c_25_playerInRange = (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed &&
                           direction.dot(GetTransform().frontVector()) > minAngle);

  if (x60c_25_playerInRange) {
    x570_boneTracking.SetActive(true);
    x5a8_targetPosition = player.GetTranslation() - (0.5f * player.GetVelocity());
    x570_boneTracking.SetTargetPosition(x5a8_targetPosition);
    x570_boneTracking.Update(dt);
    GetModelData()->GetAnimationData()->PreRender();
    x570_boneTracking.PreRender(mgr, *GetModelData()->GetAnimationData(), GetTransform(), GetModelData()->GetScale(),
                                *x450_bodyController);
  } else {
    x570_boneTracking.SetActive(false);
  }

  if (GetActive()) {
    CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId));
    if (projectile && projectile->GetActive())
      projectile->UpdateFx(GetLctrTransform(skEyeLocator), dt, mgr);
  }

  if (x60c_28_firingBeam) {
    const CGameArea* area = mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways());
    if (area->GetActive() && area->IsPostConstructed() &&
        area->GetPostConstructed()->x10dc_occlusionState == CGameArea::EOcclusionState::Occluded)
      ResetBeamState(mgr);
  }
}

void CEyeball::CreateBeam(CStateManager& mgr) {
  if (x5ec_projectileId != kInvalidUniqueId)
    return;

  CBeamInfo beamInfo(3, x5dc_beamContactFxId, x5e0_beamPulseFxId, x5e4_beamTextureId, x5e8_beamGlowTextureId, 50, 0.05f,
                     1.f, 2.f, 20.f, 1.f, 1.f, 2.f, zeus::CColor(1.f, 1.f, 1.f, 0.f), zeus::CColor(0.f, 1.f, 0.5f, 0.f),
                     150.f);
  x5ec_projectileId = mgr.AllocateUniqueId();
  mgr.AddObject(new CPlasmaProjectile(x5b4_projectileInfo.Token(), "EyeBall_Beam"sv, EWeaponType::AI, beamInfo,
                                      zeus::CTransform(), EMaterialTypes::Immovable,
                                      x5b4_projectileInfo.GetDamage(), x5ec_projectileId, GetAreaIdAlways(),
                                      GetUniqueId(), {}, false, EProjectileAttrib::KeepInCinematic));
}

void CEyeball::InActive(CStateManager&, EStateMsg msg, float) {
  if (msg == EStateMsg::Activate)
    x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
}

void CEyeball::Cover(CStateManager&, EStateMsg msg, float) {
  if (msg == EStateMsg::Activate) {
    x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
    x60c_24_canAttack = false;
    x330_stateMachineState.SetDelay(x568_attackDelay);
  }
}

void CEyeball::Flinch(CStateManager& mgr, EStateMsg msg, float arg) {
  if (msg == EStateMsg::Activate) {
    x32c_animState = EAnimState::Ready;
    x330_stateMachineState.SetDelay(x568_attackDelay);
  } else if (msg == EStateMsg::Update)
    TryCommand(mgr, pas::EAnimationState::KnockBack, CPatternedTryFunc(&CEyeball::TryFlinch), 0);
  else if (msg == EStateMsg::Deactivate)
    x32c_animState = EAnimState::NotReady;
}

void CEyeball::TryFlinch(CStateManager&, int arg) {
  x450_bodyController->GetCommandMgr().DeliverCmd(CBCKnockBackCmd(GetTransform().basis[0], pas::ESeverity(arg)));
}

void CEyeball::Active(CStateManager& mgr, EStateMsg msg, float) {
  if (msg == EStateMsg::Activate) {
    x400_24_hitByPlayerProjectile = 0;
    x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat);
    x60c_24_canAttack = false;
  } else if (msg == EStateMsg::Update) {
    if (x330_stateMachineState.GetTime() > x56c_attackStartTime)
      x60c_24_canAttack = true;

    UpdateAnimation();
  } else if (msg == EStateMsg::Deactivate) {
    x330_stateMachineState.SetDelay(x568_attackDelay);
    if (CPlasmaProjectile* proj = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId)))
      proj->ResetBeam(mgr, true);

    x60c_24_canAttack = false;

    CSfxManager::RemoveEmitter(x608_beamSfx);
    x608_beamSfx.reset();
  }
}

void CEyeball::UpdateAnimation() {
  if (std::fabs(GetModelData()->GetAnimationData()->GetAnimTimeRemaining("Whole Body"sv) - 0.f) >= 0.00001f)
    return;

  x5f0_currentAnim = (x5f0_currentAnim + 1) & 3;
  for (u32 i = 0; i < 4; ++i) {
    if (x5f4_animIdxs[x5f0_currentAnim] != -1)
      break;

    x5f0_currentAnim = (x5f0_currentAnim + 1) & 3;
  }
  s32 animIdx = x5f4_animIdxs[x5f0_currentAnim];
  if (animIdx != -1)
    x450_bodyController->GetCommandMgr().DeliverCmd(CBCScriptedCmd(animIdx, false, false, 0.f));
}

void CEyeball::ResetBeamState(CStateManager& mgr) {
  if (CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId)))
    projectile->ResetBeam(mgr, true);

  x60c_28_firingBeam = false;
  if (x608_beamSfx) {
    CSfxManager::RemoveEmitter(x608_beamSfx);
    x608_beamSfx.reset();
  }
}

void CEyeball::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) {
  if (type == EUserEventType::DamageOff)
    ResetBeamState(mgr);
  else if (type == EUserEventType::DamageOn && x60c_24_canAttack)
    FireBeam(mgr, GetLctrTransform(node.GetLocatorName()));
  else
    CPatterned::DoUserAnimEvent(mgr, node, type, dt);
}

void CEyeball::FireBeam(CStateManager& mgr, const zeus::CTransform& xf) {
  if (CPlasmaProjectile* projectile = static_cast<CPlasmaProjectile*>(mgr.ObjectById(x5ec_projectileId))) {
    if (!projectile->GetActive()) {
      projectile->Fire(xf, mgr, false);
      x60c_28_firingBeam = true;
      if (!x608_beamSfx) {
        CAudioSys::C3DEmitterParmData parmData{
            GetTranslation(), {}, 50.f, 0.1f, 0x1, x604_beamSfxId, 1.f /* 127 */, 0.15f /* 20 / 127 */, false, 127};
        x608_beamSfx = CSfxManager::AddEmitter(parmData, true, 127, true, GetAreaIdAlways());
      }
    }
  }
}

void CEyeball::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) {
  CPatterned::PreRender(mgr, frustum);
  x570_boneTracking.PreRender(mgr, *GetModelData()->GetAnimationData(), GetTransform(), GetModelData()->GetScale(),
                              *x450_bodyController);
}

void CEyeball::Death(CStateManager& mgr, const zeus::CVector3f& pos, EScriptObjectState state) {
  zeus::CTransform oldXf = GetTransform();
  CPatterned::Death(mgr, pos, state);
  SetTransform(oldXf);
}
} // namespace urde::MP1<|endoftext|>


<commit_before>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "Process.h"

#include <absl/strings/ascii.h>
#include <absl/strings/str_format.h>

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <filesystem>

#include "ElfUtils/ElfFile.h"
#include "OrbitBase/Logging.h"
#include "OrbitBase/Result.h"
#include "Utils.h"

namespace orbit_service {

void Process::UpdateCpuUsage(utils::Jiffies process_cpu_time, utils::Jiffies total_cpu_time) {
  const auto diff_process_cpu_time =
      static_cast<double>(process_cpu_time.value - previous_process_cpu_time_.value);
  const auto diff_total_cpu_time =
      static_cast<double>(total_cpu_time.value - previous_total_cpu_time_.value);

  // When the counters wrap, `cpu_usage` might be smaller than 0.0 or larger than 1.0,
  // depending on the signedness of `Jiffies`. Reference implementations like top and htop usually
  // clamp in this case. So that's what we're also doing here.
  const auto cpu_usage = std::clamp(diff_process_cpu_time / diff_total_cpu_time, 0.0, 1.0);

  // TODO(hebecker): Rename cpu_usage to cpu_usage_rate and normalize. Being in percent was
  // surprising
  set_cpu_usage(cpu_usage * 100.0);

  previous_process_cpu_time_ = process_cpu_time;
  previous_total_cpu_time_ = total_cpu_time;
}

ErrorMessageOr<Process> Process::FromPid(pid_t pid) {
  const auto path = std::filesystem::path{"/proc"} / std::to_string(pid);

  if (!std::filesystem::is_directory(path)) {
    return ErrorMessage{absl::StrFormat("PID %d does not exist", pid)};
  }

  const std::filesystem::path name_file_path = path / "comm";
  auto name_file_result = utils::ReadFileToString(name_file_path);
  if (!name_file_result) {
    return ErrorMessage{absl::StrFormat("Failed to read %s: %s", name_file_path.string(),
                                        name_file_result.error().message())};
  }

  std::string name = std::move(name_file_result.value());
  // Remove new line character.
  absl::StripTrailingAsciiWhitespace(&name);
  if (name.empty()) {
    return ErrorMessage{absl::StrFormat("Could not determine the process name of process %d", pid)};
  }

  Process process{};
  process.set_pid(pid);
  process.set_name(name);

  const auto total_cpu_time = utils::GetCumulativeTotalCpuTime();
  const auto cpu_time = utils::GetCumulativeCpuTimeFromProcess(process.pid());
  if (cpu_time && total_cpu_time) {
    process.UpdateCpuUsage(cpu_time.value(), total_cpu_time.value());
  } else {
    LOG("Could not update the CPU usage of process %d", process.pid());
  }

  // "The command-line arguments appear [...] as a set of strings
  // separated by null bytes ('\0')".
  const std::filesystem::path cmdline_file_path = path / "cmdline";
  auto cmdline_file_result = utils::ReadFileToString(cmdline_file_path);
  if (!cmdline_file_result) {
    return ErrorMessage{absl::StrFormat("Failed to read %s: %s", cmdline_file_path.string(),
                                        name_file_result.error().message())};
  }

  std::string cmdline = std::move(cmdline_file_result.value());
  std::replace(cmdline.begin(), cmdline.end(), '\0', ' ');
  process.set_command_line(cmdline);

  auto file_path_result = utils::GetExecutablePath(pid);
  if (file_path_result) {
    process.set_full_path(std::move(file_path_result.value()));

    const auto& elf_file = ElfUtils::ElfFile::Create(file_path_result.value().string());
    if (elf_file) {
      process.set_is_64_bit(elf_file.value()->Is64Bit());
    } else {
      LOG("Warning: Unable to parse the executable \"%s\" as elf file. (pid: %d)",
          file_path_result.value(), pid);
    }
  }

  return process;
}

}  // namespace orbit_service
<commit_msg>Fix copy-and-paste bug in orbit_service::Process<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "Process.h"

#include <absl/strings/ascii.h>
#include <absl/strings/str_format.h>

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <filesystem>

#include "ElfUtils/ElfFile.h"
#include "OrbitBase/Logging.h"
#include "OrbitBase/Result.h"
#include "Utils.h"

namespace orbit_service {

void Process::UpdateCpuUsage(utils::Jiffies process_cpu_time, utils::Jiffies total_cpu_time) {
  const auto diff_process_cpu_time =
      static_cast<double>(process_cpu_time.value - previous_process_cpu_time_.value);
  const auto diff_total_cpu_time =
      static_cast<double>(total_cpu_time.value - previous_total_cpu_time_.value);

  // When the counters wrap, `cpu_usage` might be smaller than 0.0 or larger than 1.0,
  // depending on the signedness of `Jiffies`. Reference implementations like top and htop usually
  // clamp in this case. So that's what we're also doing here.
  const auto cpu_usage = std::clamp(diff_process_cpu_time / diff_total_cpu_time, 0.0, 1.0);

  // TODO(hebecker): Rename cpu_usage to cpu_usage_rate and normalize. Being in percent was
  // surprising
  set_cpu_usage(cpu_usage * 100.0);

  previous_process_cpu_time_ = process_cpu_time;
  previous_total_cpu_time_ = total_cpu_time;
}

ErrorMessageOr<Process> Process::FromPid(pid_t pid) {
  const auto path = std::filesystem::path{"/proc"} / std::to_string(pid);

  if (!std::filesystem::is_directory(path)) {
    return ErrorMessage{absl::StrFormat("PID %d does not exist", pid)};
  }

  const std::filesystem::path name_file_path = path / "comm";
  auto name_file_result = utils::ReadFileToString(name_file_path);
  if (!name_file_result) {
    return ErrorMessage{absl::StrFormat("Failed to read %s: %s", name_file_path.string(),
                                        name_file_result.error().message())};
  }

  std::string name = std::move(name_file_result.value());
  // Remove new line character.
  absl::StripTrailingAsciiWhitespace(&name);
  if (name.empty()) {
    return ErrorMessage{absl::StrFormat("Could not determine the process name of process %d", pid)};
  }

  Process process{};
  process.set_pid(pid);
  process.set_name(name);

  const auto total_cpu_time = utils::GetCumulativeTotalCpuTime();
  const auto cpu_time = utils::GetCumulativeCpuTimeFromProcess(process.pid());
  if (cpu_time && total_cpu_time) {
    process.UpdateCpuUsage(cpu_time.value(), total_cpu_time.value());
  } else {
    LOG("Could not update the CPU usage of process %d", process.pid());
  }

  // "The command-line arguments appear [...] as a set of strings
  // separated by null bytes ('\0')".
  const std::filesystem::path cmdline_file_path = path / "cmdline";
  auto cmdline_file_result = utils::ReadFileToString(cmdline_file_path);
  if (!cmdline_file_result) {
    return ErrorMessage{absl::StrFormat("Failed to read %s: %s", cmdline_file_path.string(),
                                        cmdline_file_result.error().message())};
  }

  std::string cmdline = std::move(cmdline_file_result.value());
  std::replace(cmdline.begin(), cmdline.end(), '\0', ' ');
  process.set_command_line(cmdline);

  auto file_path_result = utils::GetExecutablePath(pid);
  if (file_path_result) {
    process.set_full_path(std::move(file_path_result.value()));

    const auto& elf_file = ElfUtils::ElfFile::Create(file_path_result.value().string());
    if (elf_file) {
      process.set_is_64_bit(elf_file.value()->Is64Bit());
    } else {
      LOG("Warning: Unable to parse the executable \"%s\" as elf file. (pid: %d)",
          file_path_result.value(), pid);
    }
  }

  return process;
}

}  // namespace orbit_service
<|endoftext|>