<commit_before> /*************************************************************************
 *
 *  $RCSfile: accselectionhelper.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: vg $ $Date: 2004-12-23 10:02:31 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESELECTION_HPP_
#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
#endif
#ifndef _ACCSELECTIONHELPER_HXX_
#include <accselectionhelper.hxx>
#endif

#ifndef _ACCCONTEXT_HXX
#include <acccontext.hxx>
#endif
#ifndef _ACCMAP_HXX
#include <accmap.hxx>
#endif
#ifndef _SVX_ACCESSIBILITY_ACCESSIBLE_SHAPE_HXX
#include <svx/AccessibleShape.hxx>
#endif

#ifndef _VIEWSH_HXX
#include <viewsh.hxx>
#endif
#ifndef _FESH_HXX
#include "fesh.hxx"
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>        // for SolarMutex
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace ::com::sun::star::uno;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::accessibility::XAccessible;
using ::com::sun::star::accessibility::XAccessibleContext;
using ::com::sun::star::accessibility::XAccessibleSelection;
using ::com::sun::star::lang::IndexOutOfBoundsException;

SwAccessibleSelectionHelper::SwAccessibleSelectionHelper(
    SwAccessibleContext& rCtxt ) :
        rContext( rCtxt )
{
}

SwAccessibleSelectionHelper::~SwAccessibleSelectionHelper()
{
}

SwFEShell* SwAccessibleSelectionHelper::GetFEShell()
{
    DBG_ASSERT( rContext.GetMap() != NULL, "no map?" );
    ViewShell* pViewShell = rContext.GetMap()->GetShell();
    DBG_ASSERT( pViewShell != NULL,
                "No view shell? Then what are you looking at?" );

    SwFEShell* pFEShell = NULL;
    if( pViewShell->ISA( SwFEShell ) )
    {
        pFEShell = static_cast<SwFEShell*>( pViewShell );
    }

    return pFEShell;
}

void SwAccessibleSelectionHelper::throwIndexOutOfBoundsException()
        throw ( ::com::sun::star::lang::IndexOutOfBoundsException )
{
    Reference < XAccessibleContext > xThis( &rContext );
    Reference < XAccessibleSelection >xSelThis( xThis, UNO_QUERY );
    IndexOutOfBoundsException aExcept(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("index out of bounds") ),
                xSelThis );                                     \
    throw aExcept;
}

//=====  XAccessibleSelection  ============================================

void SwAccessibleSelectionHelper::selectAccessibleChild(
    sal_Int32 nChildIndex )
    throw ( IndexOutOfBoundsException,
            RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    // Get the respective child as SwFrm (also do index checking), ...
    const SwFrmOrObj aChild = rContext.GetChild( nChildIndex );
    if( !aChild.IsValid() )
        throwIndexOutOfBoundsException();

    // we can only select fly frames, so we ignore (should: return
    // false) all other attempts at child selection
    sal_Bool bRet = sal_False;
    SwFEShell* pFEShell = GetFEShell();
    if( pFEShell != NULL )
    {
        const SdrObject *pObj = aChild.GetSdrObject();
        if( pObj )
        {
            bRet = rContext.Select( const_cast< SdrObject *>( pObj ), 0==aChild.GetSwFrm());
        }
    }
    // no frame shell, or no frame, or no fly frame -> can't select

    // return bRet;
}

sal_Bool SwAccessibleSelectionHelper::isAccessibleChildSelected(
    sal_Int32 nChildIndex )
    throw ( IndexOutOfBoundsException,
            RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    // Get the respective child as SwFrm (also do index checking), ...
    const SwFrmOrObj aChild = rContext.GetChild( nChildIndex );
    if( !aChild.IsValid() )
        throwIndexOutOfBoundsException();

    // ... and compare to the currently selected frame
    sal_Bool bRet = sal_False;
    SwFEShell* pFEShell = GetFEShell();
    if( pFEShell )
    {
        if( aChild.GetSwFrm() != 0 )
        {
            bRet = (pFEShell->GetCurrFlyFrm() == aChild.GetSwFrm());
        }
        else
        {
            bRet = pFEShell->IsObjSelected( *aChild.GetSdrObject() );
        }
    }

    return bRet;
}

void SwAccessibleSelectionHelper::clearAccessibleSelection(  )
    throw ( RuntimeException )
{
    // return sal_False     // we can't deselect
}

void SwAccessibleSelectionHelper::selectAllAccessibleChildren(  )
    throw ( RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    // We can select only one. So iterate over the children to find
    // the first we can select, and select it.

    SwFEShell* pFEShell = GetFEShell();
    if( pFEShell )
    {
        ::std::list< SwFrmOrObj > aChildren;
        rContext.GetChildren( aChildren );

        ::std::list< SwFrmOrObj >::const_iterator aIter = aChildren.begin();
        ::std::list< SwFrmOrObj >::const_iterator aEndIter = aChildren.end();
        while( aIter != aEndIter )
        {
            const SwFrmOrObj& rChild = *aIter;
            const SdrObject *pObj = rChild.GetSdrObject();
            const SwFrm* pFrm = rChild.GetSwFrm();
            if( pObj && !(pFrm != 0 && pFEShell->IsObjSelected()) )
            {
                rContext.Select( const_cast< SdrObject *>( pObj ), 0==pFrm );
                if( pFrm )
                    break;
            }
            ++aIter;
        }
    }
}

sal_Int32 SwAccessibleSelectionHelper::getSelectedAccessibleChildCount(  )
    throw ( RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    sal_Int32 nCount = 0;
    // Only one frame can be selected at a time, and we only frames
    // for selectable children.
    SwFEShell* pFEShell = GetFEShell();
    if( pFEShell != 0 )
    {
        const SwFlyFrm *pFlyFrm = pFEShell->GetCurrFlyFrm();
        if( pFlyFrm )
        {
            if( rContext.GetParent(pFlyFrm, rContext.IsInPagePreview()) ==
                rContext.GetFrm() )
            {
                nCount = 1;
            }
        }
        else
        {
            sal_uInt16 nSelObjs = pFEShell->IsObjSelected();
            if( nSelObjs > 0 )
            {
                ::std::list< SwFrmOrObj > aChildren;
                rContext.GetChildren( aChildren );

                ::std::list< SwFrmOrObj >::const_iterator aIter =
                    aChildren.begin();
                ::std::list< SwFrmOrObj >::const_iterator aEndIter =
                    aChildren.end();
                while( aIter != aEndIter && nCount < nSelObjs )
                {
                    const SwFrmOrObj& rChild = *aIter;
                    if( rChild.GetSdrObject() && !rChild.GetSwFrm() &&
                        rContext.GetParent(rChild, rContext.IsInPagePreview())
                           == rContext.GetFrm() &&
                         pFEShell->IsObjSelected( *rChild.GetSdrObject() ) )
                    {
                        nCount++;
                    }
                    ++aIter;
                }
            }
        }
    }
    return nCount;
}

Reference<XAccessible> SwAccessibleSelectionHelper::getSelectedAccessibleChild(
    sal_Int32 nSelectedChildIndex )
    throw ( IndexOutOfBoundsException,
            RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    // Since the index is relative to the selected children, and since
    // there can be at most one selected frame child, the index must
    // be 0, and a selection must exist, otherwise we have to throw an
    // IndexOutOfBoundsException
    SwFEShell* pFEShell = GetFEShell();
    if( 0 == pFEShell )
        throwIndexOutOfBoundsException();

    SwFrmOrObj aChild;
    const SwFlyFrm *pFlyFrm = pFEShell->GetCurrFlyFrm();
    if( pFlyFrm )
    {
        if( 0 == nSelectedChildIndex &&
            rContext.GetParent(pFlyFrm, rContext.IsInPagePreview()) ==
                rContext.GetFrm() )
        {
            aChild = pFlyFrm;
        }
    }
    else
    {
        sal_uInt16 nSelObjs = pFEShell->IsObjSelected();
        if( 0 == nSelObjs || nSelectedChildIndex >= nSelObjs )
            throwIndexOutOfBoundsException();

        ::std::list< SwFrmOrObj > aChildren;
        rContext.GetChildren( aChildren );

        ::std::list< SwFrmOrObj >::const_iterator aIter = aChildren.begin();
        ::std::list< SwFrmOrObj >::const_iterator aEndIter = aChildren.end();
        while( aIter != aEndIter && !aChild.IsValid() )
        {
            const SwFrmOrObj& rChild = *aIter;
            if( rChild.GetSdrObject() && !rChild.GetSwFrm() &&
                rContext.GetParent(rChild, rContext.IsInPagePreview()) ==
                    rContext.GetFrm() &&
                pFEShell->IsObjSelected( *rChild.GetSdrObject() ) )
            {
                if( 0 == nSelectedChildIndex )
                    aChild = rChild;
                else
                    --nSelectedChildIndex;
            }
            ++aIter;
        }
    }

    if( !aChild.IsValid() )
        throwIndexOutOfBoundsException();

    DBG_ASSERT( rContext.GetMap() != NULL, "We need the map." );
    Reference< XAccessible > xChild;
    if( aChild.GetSwFrm() )
    {
        ::vos::ORef < SwAccessibleContext > xChildImpl(
                rContext.GetMap()->GetContextImpl( aChild.GetSwFrm(),
                sal_True ) );
        if( xChildImpl.isValid() )
        {
            xChildImpl->SetParent( &rContext );
            xChild = xChildImpl.getBodyPtr();
        }
    }
    else
    {
        ::vos::ORef < ::accessibility::AccessibleShape > xChildImpl(
                rContext.GetMap()->GetContextImpl( aChild.GetSdrObject(),
                                          &rContext, sal_True )  );
        if( xChildImpl.isValid() )
            xChild = xChildImpl.getBodyPtr();
    }
    return xChild;
}

// --> OD 2004-11-16 #111714# - index has to be treated as global child index.
void SwAccessibleSelectionHelper::deselectAccessibleChild(
    sal_Int32 nChildIndex )
    throw ( IndexOutOfBoundsException,
            RuntimeException )
{
    // return sal_False     // we can't deselect
    if( nChildIndex < 0 ||
        nChildIndex >= rContext.GetChildCount() )
        throwIndexOutOfBoundsException();
}
<commit_msg>INTEGRATION: CWS ooo19126 (1.10.412); FILE MERGED 2005/09/05 13:38:27 rt 1.10.412.1: #i54170# Change license header: remove SISSL<commit_after> /*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: accselectionhelper.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 02:55:10 $
 *
 *  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
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESELECTION_HPP_
#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
#endif
#ifndef _ACCSELECTIONHELPER_HXX_
#include <accselectionhelper.hxx>
#endif

#ifndef _ACCCONTEXT_HXX
#include <acccontext.hxx>
#endif
#ifndef _ACCMAP_HXX
#include <accmap.hxx>
#endif
#ifndef _SVX_ACCESSIBILITY_ACCESSIBLE_SHAPE_HXX
#include <svx/AccessibleShape.hxx>
#endif

#ifndef _VIEWSH_HXX
#include <viewsh.hxx>
#endif
#ifndef _FESH_HXX
#include "fesh.hxx"
#endif

#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>        // for SolarMutex
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

using namespace ::com::sun::star::uno;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::accessibility::XAccessible;
using ::com::sun::star::accessibility::XAccessibleContext;
using ::com::sun::star::accessibility::XAccessibleSelection;
using ::com::sun::star::lang::IndexOutOfBoundsException;

SwAccessibleSelectionHelper::SwAccessibleSelectionHelper(
    SwAccessibleContext& rCtxt ) :
        rContext( rCtxt )
{
}

SwAccessibleSelectionHelper::~SwAccessibleSelectionHelper()
{
}

SwFEShell* SwAccessibleSelectionHelper::GetFEShell()
{
    DBG_ASSERT( rContext.GetMap() != NULL, "no map?" );
    ViewShell* pViewShell = rContext.GetMap()->GetShell();
    DBG_ASSERT( pViewShell != NULL,
                "No view shell? Then what are you looking at?" );

    SwFEShell* pFEShell = NULL;
    if( pViewShell->ISA( SwFEShell ) )
    {
        pFEShell = static_cast<SwFEShell*>( pViewShell );
    }

    return pFEShell;
}

void SwAccessibleSelectionHelper::throwIndexOutOfBoundsException()
        throw ( ::com::sun::star::lang::IndexOutOfBoundsException )
{
    Reference < XAccessibleContext > xThis( &rContext );
    Reference < XAccessibleSelection >xSelThis( xThis, UNO_QUERY );
    IndexOutOfBoundsException aExcept(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("index out of bounds") ),
                xSelThis );                                     \
    throw aExcept;
}

//=====  XAccessibleSelection  ============================================

void SwAccessibleSelectionHelper::selectAccessibleChild(
    sal_Int32 nChildIndex )
    throw ( IndexOutOfBoundsException,
            RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    // Get the respective child as SwFrm (also do index checking), ...
    const SwFrmOrObj aChild = rContext.GetChild( nChildIndex );
    if( !aChild.IsValid() )
        throwIndexOutOfBoundsException();

    // we can only select fly frames, so we ignore (should: return
    // false) all other attempts at child selection
    sal_Bool bRet = sal_False;
    SwFEShell* pFEShell = GetFEShell();
    if( pFEShell != NULL )
    {
        const SdrObject *pObj = aChild.GetSdrObject();
        if( pObj )
        {
            bRet = rContext.Select( const_cast< SdrObject *>( pObj ), 0==aChild.GetSwFrm());
        }
    }
    // no frame shell, or no frame, or no fly frame -> can't select

    // return bRet;
}

sal_Bool SwAccessibleSelectionHelper::isAccessibleChildSelected(
    sal_Int32 nChildIndex )
    throw ( IndexOutOfBoundsException,
            RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    // Get the respective child as SwFrm (also do index checking), ...
    const SwFrmOrObj aChild = rContext.GetChild( nChildIndex );
    if( !aChild.IsValid() )
        throwIndexOutOfBoundsException();

    // ... and compare to the currently selected frame
    sal_Bool bRet = sal_False;
    SwFEShell* pFEShell = GetFEShell();
    if( pFEShell )
    {
        if( aChild.GetSwFrm() != 0 )
        {
            bRet = (pFEShell->GetCurrFlyFrm() == aChild.GetSwFrm());
        }
        else
        {
            bRet = pFEShell->IsObjSelected( *aChild.GetSdrObject() );
        }
    }

    return bRet;
}

void SwAccessibleSelectionHelper::clearAccessibleSelection(  )
    throw ( RuntimeException )
{
    // return sal_False     // we can't deselect
}

void SwAccessibleSelectionHelper::selectAllAccessibleChildren(  )
    throw ( RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    // We can select only one. So iterate over the children to find
    // the first we can select, and select it.

    SwFEShell* pFEShell = GetFEShell();
    if( pFEShell )
    {
        ::std::list< SwFrmOrObj > aChildren;
        rContext.GetChildren( aChildren );

        ::std::list< SwFrmOrObj >::const_iterator aIter = aChildren.begin();
        ::std::list< SwFrmOrObj >::const_iterator aEndIter = aChildren.end();
        while( aIter != aEndIter )
        {
            const SwFrmOrObj& rChild = *aIter;
            const SdrObject *pObj = rChild.GetSdrObject();
            const SwFrm* pFrm = rChild.GetSwFrm();
            if( pObj && !(pFrm != 0 && pFEShell->IsObjSelected()) )
            {
                rContext.Select( const_cast< SdrObject *>( pObj ), 0==pFrm );
                if( pFrm )
                    break;
            }
            ++aIter;
        }
    }
}

sal_Int32 SwAccessibleSelectionHelper::getSelectedAccessibleChildCount(  )
    throw ( RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    sal_Int32 nCount = 0;
    // Only one frame can be selected at a time, and we only frames
    // for selectable children.
    SwFEShell* pFEShell = GetFEShell();
    if( pFEShell != 0 )
    {
        const SwFlyFrm *pFlyFrm = pFEShell->GetCurrFlyFrm();
        if( pFlyFrm )
        {
            if( rContext.GetParent(pFlyFrm, rContext.IsInPagePreview()) ==
                rContext.GetFrm() )
            {
                nCount = 1;
            }
        }
        else
        {
            sal_uInt16 nSelObjs = pFEShell->IsObjSelected();
            if( nSelObjs > 0 )
            {
                ::std::list< SwFrmOrObj > aChildren;
                rContext.GetChildren( aChildren );

                ::std::list< SwFrmOrObj >::const_iterator aIter =
                    aChildren.begin();
                ::std::list< SwFrmOrObj >::const_iterator aEndIter =
                    aChildren.end();
                while( aIter != aEndIter && nCount < nSelObjs )
                {
                    const SwFrmOrObj& rChild = *aIter;
                    if( rChild.GetSdrObject() && !rChild.GetSwFrm() &&
                        rContext.GetParent(rChild, rContext.IsInPagePreview())
                           == rContext.GetFrm() &&
                         pFEShell->IsObjSelected( *rChild.GetSdrObject() ) )
                    {
                        nCount++;
                    }
                    ++aIter;
                }
            }
        }
    }
    return nCount;
}

Reference<XAccessible> SwAccessibleSelectionHelper::getSelectedAccessibleChild(
    sal_Int32 nSelectedChildIndex )
    throw ( IndexOutOfBoundsException,
            RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    // Since the index is relative to the selected children, and since
    // there can be at most one selected frame child, the index must
    // be 0, and a selection must exist, otherwise we have to throw an
    // IndexOutOfBoundsException
    SwFEShell* pFEShell = GetFEShell();
    if( 0 == pFEShell )
        throwIndexOutOfBoundsException();

    SwFrmOrObj aChild;
    const SwFlyFrm *pFlyFrm = pFEShell->GetCurrFlyFrm();
    if( pFlyFrm )
    {
        if( 0 == nSelectedChildIndex &&
            rContext.GetParent(pFlyFrm, rContext.IsInPagePreview()) ==
                rContext.GetFrm() )
        {
            aChild = pFlyFrm;
        }
    }
    else
    {
        sal_uInt16 nSelObjs = pFEShell->IsObjSelected();
        if( 0 == nSelObjs || nSelectedChildIndex >= nSelObjs )
            throwIndexOutOfBoundsException();

        ::std::list< SwFrmOrObj > aChildren;
        rContext.GetChildren( aChildren );

        ::std::list< SwFrmOrObj >::const_iterator aIter = aChildren.begin();
        ::std::list< SwFrmOrObj >::const_iterator aEndIter = aChildren.end();
        while( aIter != aEndIter && !aChild.IsValid() )
        {
            const SwFrmOrObj& rChild = *aIter;
            if( rChild.GetSdrObject() && !rChild.GetSwFrm() &&
                rContext.GetParent(rChild, rContext.IsInPagePreview()) ==
                    rContext.GetFrm() &&
                pFEShell->IsObjSelected( *rChild.GetSdrObject() ) )
            {
                if( 0 == nSelectedChildIndex )
                    aChild = rChild;
                else
                    --nSelectedChildIndex;
            }
            ++aIter;
        }
    }

    if( !aChild.IsValid() )
        throwIndexOutOfBoundsException();

    DBG_ASSERT( rContext.GetMap() != NULL, "We need the map." );
    Reference< XAccessible > xChild;
    if( aChild.GetSwFrm() )
    {
        ::vos::ORef < SwAccessibleContext > xChildImpl(
                rContext.GetMap()->GetContextImpl( aChild.GetSwFrm(),
                sal_True ) );
        if( xChildImpl.isValid() )
        {
            xChildImpl->SetParent( &rContext );
            xChild = xChildImpl.getBodyPtr();
        }
    }
    else
    {
        ::vos::ORef < ::accessibility::AccessibleShape > xChildImpl(
                rContext.GetMap()->GetContextImpl( aChild.GetSdrObject(),
                                          &rContext, sal_True )  );
        if( xChildImpl.isValid() )
            xChild = xChildImpl.getBodyPtr();
    }
    return xChild;
}

// --> OD 2004-11-16 #111714# - index has to be treated as global child index.
void SwAccessibleSelectionHelper::deselectAccessibleChild(
    sal_Int32 nChildIndex )
    throw ( IndexOutOfBoundsException,
            RuntimeException )
{
    // return sal_False     // we can't deselect
    if( nChildIndex < 0 ||
        nChildIndex >= rContext.GetChildCount() )
        throwIndexOutOfBoundsException();
}
<|endoftext|>


<commit_before>#include "errors.h"
#include <yuni/thread/mutex.h>
#include "../grammar/nany.h"
#include <unordered_map>
#include <memory>

using namespace Yuni;

namespace ny {
namespace Logs {

struct InternalState final {
	void* userdefined = nullptr;
	Callback callback = nullptr;
};

static thread_local InternalState localHandler;

struct InternalMetadataState final {
	void* userdefined = nullptr;
	CallbackMetadata callback = nullptr;
};

static thread_local InternalMetadataState localMetadataHandler;

Handler::Handler(void* userdefined, Callback callback) {
	auto& handler = localHandler;
	// save the current state
	previousState.userdefined = handler.userdefined;
	previousState.callback    = handler.callback;
	// install the new state
	handler.userdefined = userdefined;
	handler.callback = callback;
}

Handler::~Handler() {
	// restore the previous state
	auto& handler = localHandler;
	handler.userdefined = previousState.userdefined;
	handler.callback = previousState.callback;
}

Handler::State Handler::exportThreadState() {
	auto& handler = localHandler;
	return State{handler.userdefined, handler.callback};
}

MetadataHandler::MetadataHandler(void* userdefined, CallbackMetadata callback) {
	auto& handler = localMetadataHandler;
	// save the current state
	previousState.userdefined = handler.userdefined;
	previousState.callback    = handler.callback;
	// install the new state
	handler.userdefined = userdefined;
	handler.callback = callback;
}

MetadataHandler::~MetadataHandler() {
	// restore the previous state
	auto& handler = localMetadataHandler;
	handler.userdefined = previousState.userdefined;
	handler.callback = previousState.callback;
}

void* userHandlerPointer() {
	return localMetadataHandler.userdefined;
}

} // namespace Logs
} // namespace ny

namespace ny {
namespace {

void retrieveMetadata(Logs::Report& entry, const AST::Node* node = nullptr) {
	auto& mdstate = Logs::localMetadataHandler;
	if (mdstate.callback) {
		auto& filename = entry.message.origins.location.filename;
		auto& line     = entry.message.origins.location.pos.line;
		auto& offset   = entry.message.origins.location.pos.offset;
		auto level     = entry.message.level;
		mdstate.callback(mdstate.userdefined, level, node, filename, line, offset);
	}
}

} // anonymous namespace

Logs::Report error() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::error);
	retrieveMetadata(entry);
	return entry;
}

bool error(const AnyString& msg) {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::error);
	if (not msg.empty())
		entry << msg;
	else
		entry << "(empty)";
	retrieveMetadata(entry);
	return false;
}

Logs::Report error(const AST::Node& node) {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::error);
	retrieveMetadata(entry, &node);
	return entry;
}

void error(const AST::Node& node, const AnyString& msg) {
	error(node) << msg;
}

Logs::Report warning() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::warning);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report warning(const AST::Node& node) {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::warning);
	retrieveMetadata(entry, &node);
	return entry;
}

Logs::Report ice() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::ICE);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report ice(const AST::Node& node) {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::ICE);
	retrieveMetadata(entry, &node);
	return entry;
}

bool unexpectedNode(const AST::Node& node, const AnyString& extra) {
	if (not AST::ruleIsError(node.rule)) {
		auto report = ice(node);
		auto rulename = AST::ruleToString(node.rule);
		report << "unexpected node '" << rulename << '\'';
		if (not extra.empty())
			report << ' ' << extra;
	}
	return false;
}

Logs::Report info() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::info);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report hint() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::hint);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report trace() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::trace);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report verbose() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::verbose);
	retrieveMetadata(entry);
	return entry;
}

} // namespace ny
<commit_msg>errors: fix include header<commit_after>#include "errors.h"
#include <yuni/thread/mutex.h>
#include "details/grammar/nany.h"
#include <unordered_map>
#include <memory>

using namespace Yuni;

namespace ny {
namespace Logs {

struct InternalState final {
	void* userdefined = nullptr;
	Callback callback = nullptr;
};

static thread_local InternalState localHandler;

struct InternalMetadataState final {
	void* userdefined = nullptr;
	CallbackMetadata callback = nullptr;
};

static thread_local InternalMetadataState localMetadataHandler;

Handler::Handler(void* userdefined, Callback callback) {
	auto& handler = localHandler;
	// save the current state
	previousState.userdefined = handler.userdefined;
	previousState.callback    = handler.callback;
	// install the new state
	handler.userdefined = userdefined;
	handler.callback = callback;
}

Handler::~Handler() {
	// restore the previous state
	auto& handler = localHandler;
	handler.userdefined = previousState.userdefined;
	handler.callback = previousState.callback;
}

Handler::State Handler::exportThreadState() {
	auto& handler = localHandler;
	return State{handler.userdefined, handler.callback};
}

MetadataHandler::MetadataHandler(void* userdefined, CallbackMetadata callback) {
	auto& handler = localMetadataHandler;
	// save the current state
	previousState.userdefined = handler.userdefined;
	previousState.callback    = handler.callback;
	// install the new state
	handler.userdefined = userdefined;
	handler.callback = callback;
}

MetadataHandler::~MetadataHandler() {
	// restore the previous state
	auto& handler = localMetadataHandler;
	handler.userdefined = previousState.userdefined;
	handler.callback = previousState.callback;
}

void* userHandlerPointer() {
	return localMetadataHandler.userdefined;
}

} // namespace Logs
} // namespace ny

namespace ny {
namespace {

void retrieveMetadata(Logs::Report& entry, const AST::Node* node = nullptr) {
	auto& mdstate = Logs::localMetadataHandler;
	if (mdstate.callback) {
		auto& filename = entry.message.origins.location.filename;
		auto& line     = entry.message.origins.location.pos.line;
		auto& offset   = entry.message.origins.location.pos.offset;
		auto level     = entry.message.level;
		mdstate.callback(mdstate.userdefined, level, node, filename, line, offset);
	}
}

} // anonymous namespace

Logs::Report error() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::error);
	retrieveMetadata(entry);
	return entry;
}

bool error(const AnyString& msg) {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::error);
	if (not msg.empty())
		entry << msg;
	else
		entry << "(empty)";
	retrieveMetadata(entry);
	return false;
}

Logs::Report error(const AST::Node& node) {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::error);
	retrieveMetadata(entry, &node);
	return entry;
}

void error(const AST::Node& node, const AnyString& msg) {
	error(node) << msg;
}

Logs::Report warning() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::warning);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report warning(const AST::Node& node) {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::warning);
	retrieveMetadata(entry, &node);
	return entry;
}

Logs::Report ice() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::ICE);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report ice(const AST::Node& node) {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::ICE);
	retrieveMetadata(entry, &node);
	return entry;
}

bool unexpectedNode(const AST::Node& node, const AnyString& extra) {
	if (not AST::ruleIsError(node.rule)) {
		auto report = ice(node);
		auto rulename = AST::ruleToString(node.rule);
		report << "unexpected node '" << rulename << '\'';
		if (not extra.empty())
			report << ' ' << extra;
	}
	return false;
}

Logs::Report info() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::info);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report hint() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::hint);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report trace() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::trace);
	retrieveMetadata(entry);
	return entry;
}

Logs::Report verbose() {
	auto& state = Logs::localHandler;
	auto entry = state.callback(state.userdefined, Logs::Level::verbose);
	retrieveMetadata(entry);
	return entry;
}

} // namespace ny
<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Microsoft Corporation
 *
 * -=- Robust Distributed System Nucleus (rDSN) -=-
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/*
 * Description:
 *     What is this file about?
 *
 * Revision history:
 *     xxxx-xx-xx, author, first version
 *     xxxx-xx-xx, author, fix bug about xxx
 */

#include "prepare_list.h"
#include "mutation.h"

# ifdef __TITLE__
# undef __TITLE__
# endif
# define __TITLE__ "prepare_list"

namespace dsn { namespace replication {

prepare_list::prepare_list(
        decree init_decree, int max_count,
        mutation_committer committer
        )
        : mutation_cache(init_decree, max_count)
{
    _committer = committer;
    _last_committed_decree = init_decree;
}

void prepare_list::sanity_check()
{

}

void prepare_list::reset(decree init_decree)
{
    _last_committed_decree = init_decree;
    mutation_cache::reset(init_decree, true);
}

void prepare_list::truncate(decree init_decree)
{
    while (min_decree() <= init_decree && count() > 0)
    {
        pop_min();
    }

    if (count() == 0)
    {
        mutation_cache::reset(init_decree, true);
    }

    _last_committed_decree = init_decree;
}

error_code prepare_list::prepare(mutation_ptr& mu, partition_status status)
{
    decree d = mu->data.header.decree;
    dassert (d > last_committed_decree(), "");

    // pop committed mutations if buffer is full
    while (d - min_decree() >= capacity() && last_committed_decree() > min_decree())
    {
        pop_min();
    }

    error_code err;
    switch (status)
    {
    case PS_PRIMARY:
        return mutation_cache::put(mu);

    case PS_SECONDARY:
    case PS_POTENTIAL_SECONDARY:
        // all mutations with lower decree must be ready
        commit(mu->data.header.last_committed_decree, COMMIT_TO_DECREE_HARD);
        err = mutation_cache::put(mu);
        dassert (err == ERR_OK, "");
        return err;

    //// delayed commit - only when capacity is an issue
    //case PS_POTENTIAL_SECONDARY:
    //    while (true)
    //    {
    //        err = mutation_cache::put(mu);
    //        if (err == ERR_CAPACITY_EXCEEDED)
    //        {
    //            dassert(mu->data.header.last_committed_decree >= min_decree(), "");
    //            commit (min_decree(), true);
    //            pop_min();
    //        }
    //        else
    //            break;
    //    }
    //    dassert (err == ERR_OK, "");
    //    return err;

    case PS_INACTIVE: // only possible during init
        if (mu->data.header.last_committed_decree > max_decree())
        {
            reset(mu->data.header.last_committed_decree);
        }
        else if (mu->data.header.last_committed_decree > _last_committed_decree)
        {
            commit(mu->data.header.last_committed_decree, COMMIT_TO_DECREE_HARD);
        }
        err = mutation_cache::put(mu);
        dassert (err == ERR_OK, "");
        return err;

    default:
        dassert (false, "");
        return 0;
    }
}

//
// ordered commit
//
bool prepare_list::commit(decree d, commit_type ct)
{
    if (d <= last_committed_decree())
        return false;

    dinfo("commit to decree %" PRId64, d);

    ballot last_bt = 0;
    switch (ct)
    {
    case COMMIT_TO_DECREE_HARD:
        {
            for (decree d0 = last_committed_decree() + 1; d0 <= d; d0++)
            {
                mutation_ptr mu = get_mutation_by_decree(d0);
                dassert(mu != nullptr &&
                    (mu->is_logged()) &&
                    mu->data.header.ballot >= last_bt,
                    "mutation %" PRId64 " is missing in prepare list",
                    d0
                    );

                _last_committed_decree++;
                last_bt = mu->data.header.ballot;
                _committer(mu);
            }

            sanity_check();
            return true;
        }
    case COMMIT_TO_DECREE_SOFT:
        {
            for (decree d0 = last_committed_decree() + 1; d0 <= d; d0++)
            {
                mutation_ptr mu = get_mutation_by_decree(d0);
                if (mu != nullptr && mu->is_ready_for_commit() && mu->data.header.ballot >= last_bt)
                {
                    _last_committed_decree++;
                    last_bt = mu->data.header.ballot;
                    _committer(mu);
                }
                else
                    break;
            }

            sanity_check();
            return true;
        }
    case COMMIT_ALL_READY:
        {
            if (d != last_committed_decree() + 1)
                return false;

            int count = 0;
            mutation_ptr mu = get_mutation_by_decree(last_committed_decree() + 1);

            while (mu != nullptr && mu->is_ready_for_commit() && mu->data.header.ballot >= last_bt)
            {
                _last_committed_decree++;
                last_bt = mu->data.header.ballot;
                _committer(mu);
                count++;
                mu = mutation_cache::get_mutation_by_decree(_last_committed_decree + 1);
            }

            sanity_check();
            return count > 0;
        }
    default:
        dassert(false, "invalid commit type %d", (int)ct);
    }

    return false;
}

}} // namespace end
<commit_msg>smallfix<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Microsoft Corporation
 *
 * -=- Robust Distributed System Nucleus (rDSN) -=-
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/*
 * Description:
 *     What is this file about?
 *
 * Revision history:
 *     xxxx-xx-xx, author, first version
 *     xxxx-xx-xx, author, fix bug about xxx
 */

#include "prepare_list.h"
#include "mutation.h"

# ifdef __TITLE__
# undef __TITLE__
# endif
# define __TITLE__ "prepare_list"

namespace dsn { namespace replication {

prepare_list::prepare_list(
        decree init_decree, int max_count,
        mutation_committer committer
        )
        : mutation_cache(init_decree, max_count)
{
    _committer = committer;
    _last_committed_decree = init_decree;
}

void prepare_list::sanity_check()
{

}

void prepare_list::reset(decree init_decree)
{
    _last_committed_decree = init_decree;
    mutation_cache::reset(init_decree, true);
}

void prepare_list::truncate(decree init_decree)
{
    while (min_decree() <= init_decree && count() > 0)
    {
        pop_min();
    }

    if (count() == 0)
    {
        mutation_cache::reset(init_decree, true);
    }

    _last_committed_decree = init_decree;
}

error_code prepare_list::prepare(mutation_ptr& mu, partition_status status)
{
    decree d = mu->data.header.decree;
    dassert (d > last_committed_decree(), "");

    // pop committed mutations if buffer is full
    while (d - min_decree() >= capacity() && last_committed_decree() > min_decree())
    {
        pop_min();
    }

    error_code err;
    switch (status)
    {
    case PS_PRIMARY:
        return mutation_cache::put(mu);

    case PS_SECONDARY:
    case PS_POTENTIAL_SECONDARY:
        // all mutations with lower decree must be ready
        commit(mu->data.header.last_committed_decree, COMMIT_TO_DECREE_HARD);
        err = mutation_cache::put(mu);
        dassert (err == ERR_OK, "");
        return err;

    //// delayed commit - only when capacity is an issue
    //case PS_POTENTIAL_SECONDARY:
    //    while (true)
    //    {
    //        err = mutation_cache::put(mu);
    //        if (err == ERR_CAPACITY_EXCEEDED)
    //        {
    //            dassert(mu->data.header.last_committed_decree >= min_decree(), "");
    //            commit (min_decree(), true);
    //            pop_min();
    //        }
    //        else
    //            break;
    //    }
    //    dassert (err == ERR_OK, "");
    //    return err;

    case PS_INACTIVE: // only possible during init
        if (mu->data.header.last_committed_decree > max_decree())
        {
            reset(mu->data.header.last_committed_decree);
        }
        else if (mu->data.header.last_committed_decree > _last_committed_decree)
        {
            commit(mu->data.header.last_committed_decree, COMMIT_TO_DECREE_HARD);
        }
        err = mutation_cache::put(mu);
        dassert (err == ERR_OK, "");
        return err;

    default:
        dassert (false, "");
        return 0;
    }
}

//
// ordered commit
//
bool prepare_list::commit(decree d, commit_type ct)
{
    if (d <= last_committed_decree())
        return false;

    ballot last_bt = 0;
    switch (ct)
    {
    case COMMIT_TO_DECREE_HARD:
        {
            for (decree d0 = last_committed_decree() + 1; d0 <= d; d0++)
            {
                mutation_ptr mu = get_mutation_by_decree(d0);
                dassert(mu != nullptr &&
                    (mu->is_logged()) &&
                    mu->data.header.ballot >= last_bt,
                    "mutation %" PRId64 " is missing in prepare list",
                    d0
                    );

                _last_committed_decree++;
                last_bt = mu->data.header.ballot;
                _committer(mu);
            }

            sanity_check();
            return true;
        }
    case COMMIT_TO_DECREE_SOFT:
        {
            for (decree d0 = last_committed_decree() + 1; d0 <= d; d0++)
            {
                mutation_ptr mu = get_mutation_by_decree(d0);
                if (mu != nullptr && mu->is_ready_for_commit() && mu->data.header.ballot >= last_bt)
                {
                    _last_committed_decree++;
                    last_bt = mu->data.header.ballot;
                    _committer(mu);
                }
                else
                    break;
            }

            sanity_check();
            return true;
        }
    case COMMIT_ALL_READY:
        {
            if (d != last_committed_decree() + 1)
                return false;

            int count = 0;
            mutation_ptr mu = get_mutation_by_decree(last_committed_decree() + 1);

            while (mu != nullptr && mu->is_ready_for_commit() && mu->data.header.ballot >= last_bt)
            {
                _last_committed_decree++;
                last_bt = mu->data.header.ballot;
                _committer(mu);
                count++;
                mu = mutation_cache::get_mutation_by_decree(_last_committed_decree + 1);
            }

            sanity_check();
            return count > 0;
        }
    default:
        dassert(false, "invalid commit type %d", (int)ct);
    }

    return false;
}

}} // namespace end
<|endoftext|>


<commit_before>// Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2020 - 2022 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.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_POSH_ICEORYX_POSH_TYPES_HPP
#define IOX_POSH_ICEORYX_POSH_TYPES_HPP

#include "iceoryx_hoofs/cxx/method_callback.hpp"
#include "iceoryx_hoofs/cxx/string.hpp"
#include "iceoryx_hoofs/cxx/variant_queue.hpp"
#include "iceoryx_hoofs/cxx/vector.hpp"
#include "iceoryx_hoofs/internal/posix_wrapper/ipc_channel.hpp"
#include "iceoryx_hoofs/internal/units/duration.hpp"
#include "iceoryx_hoofs/log/logstream.hpp"
#include "iceoryx_hoofs/platform/platform_settings.hpp"
#include "iceoryx_posh/iceoryx_posh_deployment.hpp"

#include <cstdint>

namespace iox
{
namespace popo
{
class UniquePortId;
struct BasePortData;

class PublisherPortRouDi;
class PublisherPortUser;
class SubscriberPortRouDi;
class SubscriberPortUser;
} // namespace popo
namespace capro
{
class ServiceDescription;
}

using PublisherPortRouDiType = iox::popo::PublisherPortRouDi;
using PublisherPortUserType = iox::popo::PublisherPortUser;
using SubscriberPortRouDiType = iox::popo::SubscriberPortRouDi;
using SubscriberPortUserType = iox::popo::SubscriberPortUser;

using SubscriberPortType = iox::build::CommunicationPolicy;

//--------- Communication Resources Start---------------------
// Publisher
constexpr uint32_t MAX_PUBLISHERS = build::IOX_MAX_PUBLISHERS;
constexpr uint32_t MAX_SUBSCRIBERS_PER_PUBLISHER = build::IOX_MAX_SUBSCRIBERS_PER_PUBLISHER;
constexpr uint32_t MAX_CHUNKS_ALLOCATED_PER_PUBLISHER_SIMULTANEOUSLY =
    build::IOX_MAX_CHUNKS_ALLOCATED_PER_PUBLISHER_SIMULTANEOUSLY;
constexpr uint64_t MAX_PUBLISHER_HISTORY = build::IOX_MAX_PUBLISHER_HISTORY;
// Subscriber
constexpr uint32_t MAX_SUBSCRIBERS = build::IOX_MAX_SUBSCRIBERS;
constexpr uint32_t MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY =
    build::IOX_MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY;
constexpr uint32_t MAX_SUBSCRIBER_QUEUE_CAPACITY = MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY;
// Introspection is using the following publisherPorts, which reduced the number of ports available for the user
// 1x publisherPort mempool introspection
// 1x publisherPort process introspection
// 3x publisherPort port introspection
constexpr uint32_t PUBLISHERS_RESERVED_FOR_INTROSPECTION = 5;
constexpr uint32_t PUBLISHERS_RESERVED_FOR_SERVICE_REGISTRY = 1;
constexpr uint32_t NUMBER_OF_INTERNAL_PUBLISHERS =
    PUBLISHERS_RESERVED_FOR_INTROSPECTION + PUBLISHERS_RESERVED_FOR_SERVICE_REGISTRY;
/// With MAX_SUBSCRIBER_QUEUE_CAPACITY = MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY we couple the maximum number of
/// chunks a user is allowed to hold with the maximum queue capacity. This allows that a polling user can replace all
/// the held chunks in one execution with all new ones from a completely filled queue. Or the other way round, when we
/// have a contract with the user regarding how many chunks they are allowed to hold, then the queue size needs not be
/// bigger. We can provide this number of newest chunks, more the user would not be allowed to hold anyway
// Gateway
constexpr uint32_t MAX_INTERFACE_NUMBER = build::IOX_MAX_INTERFACE_NUMBER;
constexpr uint32_t MAX_INTERFACE_CAPRO_FIFO_SIZE = MAX_PUBLISHERS;
constexpr uint32_t MAX_CHANNEL_NUMBER = MAX_PUBLISHERS + MAX_SUBSCRIBERS;
constexpr uint32_t MAX_GATEWAY_SERVICES = 2 * MAX_CHANNEL_NUMBER;
// Client
constexpr uint32_t MAX_CLIENTS = build::IOX_MAX_SUBSCRIBERS; /// @todo
constexpr uint32_t MAX_REQUESTS_ALLOCATED_SIMULTANEOUSLY = 4U;
constexpr uint32_t MAX_RESPONSES_PROCESSED_SIMULTANEOUSLY = 16U;
constexpr uint32_t MAX_RESPONSE_QUEUE_CAPACITY = 16U;
// Server
constexpr uint32_t MAX_SERVERS = build::IOX_MAX_PUBLISHERS; /// @todo
constexpr uint32_t MAX_CLIENTS_PER_SERVER = 256U;
constexpr uint32_t MAX_REQUESTS_PROCESSED_SIMULTANEOUSLY = 4U;
constexpr uint32_t MAX_RESPONSES_ALLOCATED_SIMULTANEOUSLY = MAX_REQUESTS_PROCESSED_SIMULTANEOUSLY;
constexpr uint32_t MAX_REQUEST_QUEUE_CAPACITY = 1024;
// Waitset
namespace popo
{
using WaitSetIsConditionSatisfiedCallback = cxx::ConstMethodCallback<bool>;
}
constexpr uint32_t MAX_NUMBER_OF_CONDITION_VARIABLES = 1024U;
constexpr uint32_t MAX_NUMBER_OF_NOTIFIERS_PER_CONDITION_VARIABLE = 128U;
constexpr uint32_t MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET = 128U;
static_assert(MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET <= MAX_NUMBER_OF_NOTIFIERS_PER_CONDITION_VARIABLE,
              "The WaitSet capacity is restricted by the maximum amount of notifiers per condition variable.");
// Listener
constexpr uint8_t MAX_NUMBER_OF_EVENTS_PER_LISTENER = 128U;
static_assert(MAX_NUMBER_OF_EVENTS_PER_LISTENER <= MAX_NUMBER_OF_NOTIFIERS_PER_CONDITION_VARIABLE,
              "The Listener capacity is restricted by the maximum amount of notifiers per condition variable.");
//--------- Communication Resources End---------------------

// Memory
constexpr uint32_t MAX_NUMBER_OF_MEMPOOLS = 32U;
constexpr uint32_t MAX_SHM_SEGMENTS = 100U;

constexpr uint32_t MAX_NUMBER_OF_MEMORY_PROVIDER = 8U;
constexpr uint32_t MAX_NUMBER_OF_MEMORY_BLOCKS_PER_MEMORY_PROVIDER = 64U;

constexpr uint32_t CHUNK_DEFAULT_USER_PAYLOAD_ALIGNMENT{8U};
constexpr uint32_t CHUNK_NO_USER_HEADER_SIZE{0U};
constexpr uint32_t CHUNK_NO_USER_HEADER_ALIGNMENT{1U};

// Message Queue
constexpr uint32_t ROUDI_MAX_MESSAGES = 5U;
constexpr uint32_t ROUDI_MESSAGE_SIZE = 512U;
constexpr uint32_t APP_MAX_MESSAGES = 5U;
constexpr uint32_t APP_MESSAGE_SIZE = 512U;

// Processes
constexpr uint32_t MAX_PROCESS_NUMBER = 300U;
/// Maximum number of services, which can be found.
/// This limitation is coming due to the fixed capacity of the cxx::vector (This doesn't limit the offered number of
/// instances)
/// @todo #415 increase number back to 50 once service registry is available via shared memory
/// @todo #1074 define and set the limits concerning the service discovery
constexpr uint32_t MAX_NUMBER_OF_SERVICES = 10U;
constexpr const char SERVICE_REGISTRY_SERVICE_NAME[] = "ServiceRegistry";
constexpr const char SERVICE_REGISTRY_INSTANCE_NAME[] = "RouDi_ID";
constexpr const char SERVICE_REGISTRY_EVENT_NAME[] = "ServiceRegistry";

// Nodes
constexpr uint32_t MAX_NODE_NUMBER = 1000U;
constexpr uint32_t MAX_NODE_PER_PROCESS = 50U;

constexpr uint32_t MAX_RUNTIME_NAME_LENGTH = MAX_IPC_CHANNEL_NAME_LENGTH;

static_assert(MAX_PROCESS_NUMBER * MAX_NODE_PER_PROCESS > MAX_NODE_NUMBER, "Invalid configuration for nodes");

enum class SubscribeState : uint32_t
{
    NOT_SUBSCRIBED = 0,
    SUBSCRIBE_REQUESTED,
    SUBSCRIBED,
    UNSUBSCRIBE_REQUESTED,
    WAIT_FOR_OFFER
};

enum class ConnectionState : uint32_t
{
    NOT_CONNECTED = 0,
    CONNECT_REQUESTED,
    CONNECTED,
    DISCONNECT_REQUESTED,
    WAIT_FOR_OFFER
};

/// @brief Converts the ConnectionState to a string literal
/// @param[in] value to convert to a string literal
/// @return pointer to a string literal
inline constexpr const char* asStringLiteral(ConnectionState value) noexcept;

/// @brief Convenience stream operator to easily use the `asStringLiteral` function with std::ostream
/// @param[in] stream sink to write the message to
/// @param[in] value to convert to a string literal
/// @return the reference to `stream` which was provided as input parameter
inline std::ostream& operator<<(std::ostream& stream, ConnectionState value) noexcept;

/// @brief Convenience stream operator to easily use the `asStringLiteral` function with iox::log::LogStream
/// @param[in] stream sink to write the message to
/// @param[in] value to convert to a string literal
/// @return the reference to `stream` which was provided as input parameter
inline log::LogStream& operator<<(log::LogStream& stream, ConnectionState value) noexcept;

// Default properties of ChunkDistributorData
struct DefaultChunkDistributorConfig
{
    static constexpr uint32_t MAX_QUEUES = MAX_SUBSCRIBERS_PER_PUBLISHER;
    static constexpr uint64_t MAX_HISTORY_CAPACITY = MAX_PUBLISHER_HISTORY;
};

// Default properties of ChunkQueueData
struct DefaultChunkQueueConfig
{
    static constexpr uint64_t MAX_QUEUE_CAPACITY = MAX_SUBSCRIBER_QUEUE_CAPACITY;
};

// alias for cxx::string
using RuntimeName_t = cxx::string<MAX_RUNTIME_NAME_LENGTH>;
using NodeName_t = cxx::string<100>;
using ShmName_t = cxx::string<128>;

namespace capro
{
using IdString_t = cxx::string<100>;
}

/// @todo Move everything in this namespace to iceoryx_roudi_types.hpp once we move RouDi to a separate CMake target
namespace roudi
{
using ConfigFilePathString_t = cxx::string<1024>;

constexpr const char ROUDI_LOCK_NAME[] = "iox-unique-roudi";
constexpr const char IPC_CHANNEL_ROUDI_NAME[] = "roudi";

/// shared memmory segment for the iceoryx managment data
constexpr const char SHM_NAME[] = "iceoryx_mgmt";

// this is used by the UniquePortId
constexpr uint16_t DEFAULT_UNIQUE_ROUDI_ID{0U};

// Timeout
using namespace units::duration_literals;
constexpr units::Duration PROCESS_DEFAULT_KILL_DELAY = 45_s;
constexpr units::Duration PROCESS_TERMINATED_CHECK_INTERVAL = 250_ms;
constexpr units::Duration DISCOVERY_INTERVAL = 100_ms;

/// @brief Controls process alive monitoring. Upon timeout, a monitored process is removed
/// and its resources are made available. The process can then start and register itself again.
/// Contrarily, unmonitored processes can be restarted but registration will fail.
/// Once Runlevel Management is extended, it will detect absent processes. Those processes can register again.
/// ON - all processes are monitored
/// OFF - no process is monitored
enum class MonitoringMode
{
    ON,
    OFF
};

iox::log::LogStream& operator<<(iox::log::LogStream& logstream, const MonitoringMode& mode) noexcept;
} // namespace roudi

namespace mepoo
{
using SequenceNumber_t = std::uint64_t;
using BaseClock_t = std::chrono::steady_clock;

// use signed integer for duration;
// there is a bug in gcc 4.8 which leads to a wrong calcutated time
// when sleep_until() is used with a timepoint in the past
using DurationNs_t = std::chrono::duration<std::int64_t, std::nano>;
using TimePointNs_t = std::chrono::time_point<BaseClock_t, DurationNs_t>;
} // namespace mepoo

namespace runtime
{
using ServiceContainer = iox::cxx::vector<capro::ServiceDescription, MAX_NUMBER_OF_SERVICES>;
using namespace units::duration_literals;
constexpr units::Duration PROCESS_WAITING_FOR_ROUDI_TIMEOUT = 60_s;
constexpr units::Duration PROCESS_KEEP_ALIVE_INTERVAL = 3 * roudi::DISCOVERY_INTERVAL;  // > DISCOVERY_INTERVAL
constexpr units::Duration PROCESS_KEEP_ALIVE_TIMEOUT = 5 * PROCESS_KEEP_ALIVE_INTERVAL; // > PROCESS_KEEP_ALIVE_INTERVAL
} // namespace runtime

namespace version
{
static const uint64_t COMMIT_ID_STRING_SIZE = 12u;
using CommitIdString_t = cxx::string<COMMIT_ID_STRING_SIZE>;
static const uint64_t BUILD_DATE_STRING_SIZE = 36u;
using BuildDateString_t = cxx::string<BUILD_DATE_STRING_SIZE>;
} // namespace version

} // namespace iox

#include "iceoryx_posh/iceoryx_posh_types.inl"

#endif // IOX_POSH_ICEORYX_POSH_TYPES_HPP
<commit_msg>iox-#415 Increase MAX_NUMBER_OF_SERVICES to a usable value<commit_after>// Copyright (c) 2019 - 2020 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2020 - 2022 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.
//
// SPDX-License-Identifier: Apache-2.0
#ifndef IOX_POSH_ICEORYX_POSH_TYPES_HPP
#define IOX_POSH_ICEORYX_POSH_TYPES_HPP

#include "iceoryx_hoofs/cxx/method_callback.hpp"
#include "iceoryx_hoofs/cxx/string.hpp"
#include "iceoryx_hoofs/cxx/variant_queue.hpp"
#include "iceoryx_hoofs/cxx/vector.hpp"
#include "iceoryx_hoofs/internal/posix_wrapper/ipc_channel.hpp"
#include "iceoryx_hoofs/internal/units/duration.hpp"
#include "iceoryx_hoofs/log/logstream.hpp"
#include "iceoryx_hoofs/platform/platform_settings.hpp"
#include "iceoryx_posh/iceoryx_posh_deployment.hpp"

#include <cstdint>

namespace iox
{
namespace popo
{
class UniquePortId;
struct BasePortData;

class PublisherPortRouDi;
class PublisherPortUser;
class SubscriberPortRouDi;
class SubscriberPortUser;
} // namespace popo
namespace capro
{
class ServiceDescription;
}

using PublisherPortRouDiType = iox::popo::PublisherPortRouDi;
using PublisherPortUserType = iox::popo::PublisherPortUser;
using SubscriberPortRouDiType = iox::popo::SubscriberPortRouDi;
using SubscriberPortUserType = iox::popo::SubscriberPortUser;

using SubscriberPortType = iox::build::CommunicationPolicy;

//--------- Communication Resources Start---------------------
// Publisher
constexpr uint32_t MAX_PUBLISHERS = build::IOX_MAX_PUBLISHERS;
constexpr uint32_t MAX_SUBSCRIBERS_PER_PUBLISHER = build::IOX_MAX_SUBSCRIBERS_PER_PUBLISHER;
constexpr uint32_t MAX_CHUNKS_ALLOCATED_PER_PUBLISHER_SIMULTANEOUSLY =
    build::IOX_MAX_CHUNKS_ALLOCATED_PER_PUBLISHER_SIMULTANEOUSLY;
constexpr uint64_t MAX_PUBLISHER_HISTORY = build::IOX_MAX_PUBLISHER_HISTORY;
// Subscriber
constexpr uint32_t MAX_SUBSCRIBERS = build::IOX_MAX_SUBSCRIBERS;
constexpr uint32_t MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY =
    build::IOX_MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY;
constexpr uint32_t MAX_SUBSCRIBER_QUEUE_CAPACITY = MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY;
// Introspection is using the following publisherPorts, which reduced the number of ports available for the user
// 1x publisherPort mempool introspection
// 1x publisherPort process introspection
// 3x publisherPort port introspection
constexpr uint32_t PUBLISHERS_RESERVED_FOR_INTROSPECTION = 5;
constexpr uint32_t PUBLISHERS_RESERVED_FOR_SERVICE_REGISTRY = 1;
constexpr uint32_t NUMBER_OF_INTERNAL_PUBLISHERS =
    PUBLISHERS_RESERVED_FOR_INTROSPECTION + PUBLISHERS_RESERVED_FOR_SERVICE_REGISTRY;
/// With MAX_SUBSCRIBER_QUEUE_CAPACITY = MAX_CHUNKS_HELD_PER_SUBSCRIBER_SIMULTANEOUSLY we couple the maximum number of
/// chunks a user is allowed to hold with the maximum queue capacity. This allows that a polling user can replace all
/// the held chunks in one execution with all new ones from a completely filled queue. Or the other way round, when we
/// have a contract with the user regarding how many chunks they are allowed to hold, then the queue size needs not be
/// bigger. We can provide this number of newest chunks, more the user would not be allowed to hold anyway
// Gateway
constexpr uint32_t MAX_INTERFACE_NUMBER = build::IOX_MAX_INTERFACE_NUMBER;
constexpr uint32_t MAX_INTERFACE_CAPRO_FIFO_SIZE = MAX_PUBLISHERS;
constexpr uint32_t MAX_CHANNEL_NUMBER = MAX_PUBLISHERS + MAX_SUBSCRIBERS;
constexpr uint32_t MAX_GATEWAY_SERVICES = 2 * MAX_CHANNEL_NUMBER;
// Client
constexpr uint32_t MAX_CLIENTS = build::IOX_MAX_SUBSCRIBERS; /// @todo
constexpr uint32_t MAX_REQUESTS_ALLOCATED_SIMULTANEOUSLY = 4U;
constexpr uint32_t MAX_RESPONSES_PROCESSED_SIMULTANEOUSLY = 16U;
constexpr uint32_t MAX_RESPONSE_QUEUE_CAPACITY = 16U;
// Server
constexpr uint32_t MAX_SERVERS = build::IOX_MAX_PUBLISHERS; /// @todo
constexpr uint32_t MAX_CLIENTS_PER_SERVER = 256U;
constexpr uint32_t MAX_REQUESTS_PROCESSED_SIMULTANEOUSLY = 4U;
constexpr uint32_t MAX_RESPONSES_ALLOCATED_SIMULTANEOUSLY = MAX_REQUESTS_PROCESSED_SIMULTANEOUSLY;
constexpr uint32_t MAX_REQUEST_QUEUE_CAPACITY = 1024;
// Waitset
namespace popo
{
using WaitSetIsConditionSatisfiedCallback = cxx::ConstMethodCallback<bool>;
}
constexpr uint32_t MAX_NUMBER_OF_CONDITION_VARIABLES = 1024U;
constexpr uint32_t MAX_NUMBER_OF_NOTIFIERS_PER_CONDITION_VARIABLE = 128U;
constexpr uint32_t MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET = 128U;
static_assert(MAX_NUMBER_OF_ATTACHMENTS_PER_WAITSET <= MAX_NUMBER_OF_NOTIFIERS_PER_CONDITION_VARIABLE,
              "The WaitSet capacity is restricted by the maximum amount of notifiers per condition variable.");
// Listener
constexpr uint8_t MAX_NUMBER_OF_EVENTS_PER_LISTENER = 128U;
static_assert(MAX_NUMBER_OF_EVENTS_PER_LISTENER <= MAX_NUMBER_OF_NOTIFIERS_PER_CONDITION_VARIABLE,
              "The Listener capacity is restricted by the maximum amount of notifiers per condition variable.");
//--------- Communication Resources End---------------------

// Memory
constexpr uint32_t MAX_NUMBER_OF_MEMPOOLS = 32U;
constexpr uint32_t MAX_SHM_SEGMENTS = 100U;

constexpr uint32_t MAX_NUMBER_OF_MEMORY_PROVIDER = 8U;
constexpr uint32_t MAX_NUMBER_OF_MEMORY_BLOCKS_PER_MEMORY_PROVIDER = 64U;

constexpr uint32_t CHUNK_DEFAULT_USER_PAYLOAD_ALIGNMENT{8U};
constexpr uint32_t CHUNK_NO_USER_HEADER_SIZE{0U};
constexpr uint32_t CHUNK_NO_USER_HEADER_ALIGNMENT{1U};

// Message Queue
constexpr uint32_t ROUDI_MAX_MESSAGES = 5U;
constexpr uint32_t ROUDI_MESSAGE_SIZE = 512U;
constexpr uint32_t APP_MAX_MESSAGES = 5U;
constexpr uint32_t APP_MESSAGE_SIZE = 512U;

// Processes
constexpr uint32_t MAX_PROCESS_NUMBER = 300U;
/// Maximum number of services, which can be found.
/// This limitation is coming due to the fixed capacity of the cxx::vector (This doesn't limit the offered number of
/// instances)
/// @todo #1074 define and set the limits concerning the service discovery
constexpr uint32_t MAX_NUMBER_OF_SERVICES = 100U;
constexpr const char SERVICE_REGISTRY_SERVICE_NAME[] = "ServiceRegistry";
constexpr const char SERVICE_REGISTRY_INSTANCE_NAME[] = "RouDi_ID";
constexpr const char SERVICE_REGISTRY_EVENT_NAME[] = "ServiceRegistry";

// Nodes
constexpr uint32_t MAX_NODE_NUMBER = 1000U;
constexpr uint32_t MAX_NODE_PER_PROCESS = 50U;

constexpr uint32_t MAX_RUNTIME_NAME_LENGTH = MAX_IPC_CHANNEL_NAME_LENGTH;

static_assert(MAX_PROCESS_NUMBER * MAX_NODE_PER_PROCESS > MAX_NODE_NUMBER, "Invalid configuration for nodes");

enum class SubscribeState : uint32_t
{
    NOT_SUBSCRIBED = 0,
    SUBSCRIBE_REQUESTED,
    SUBSCRIBED,
    UNSUBSCRIBE_REQUESTED,
    WAIT_FOR_OFFER
};

enum class ConnectionState : uint32_t
{
    NOT_CONNECTED = 0,
    CONNECT_REQUESTED,
    CONNECTED,
    DISCONNECT_REQUESTED,
    WAIT_FOR_OFFER
};

/// @brief Converts the ConnectionState to a string literal
/// @param[in] value to convert to a string literal
/// @return pointer to a string literal
inline constexpr const char* asStringLiteral(ConnectionState value) noexcept;

/// @brief Convenience stream operator to easily use the `asStringLiteral` function with std::ostream
/// @param[in] stream sink to write the message to
/// @param[in] value to convert to a string literal
/// @return the reference to `stream` which was provided as input parameter
inline std::ostream& operator<<(std::ostream& stream, ConnectionState value) noexcept;

/// @brief Convenience stream operator to easily use the `asStringLiteral` function with iox::log::LogStream
/// @param[in] stream sink to write the message to
/// @param[in] value to convert to a string literal
/// @return the reference to `stream` which was provided as input parameter
inline log::LogStream& operator<<(log::LogStream& stream, ConnectionState value) noexcept;

// Default properties of ChunkDistributorData
struct DefaultChunkDistributorConfig
{
    static constexpr uint32_t MAX_QUEUES = MAX_SUBSCRIBERS_PER_PUBLISHER;
    static constexpr uint64_t MAX_HISTORY_CAPACITY = MAX_PUBLISHER_HISTORY;
};

// Default properties of ChunkQueueData
struct DefaultChunkQueueConfig
{
    static constexpr uint64_t MAX_QUEUE_CAPACITY = MAX_SUBSCRIBER_QUEUE_CAPACITY;
};

// alias for cxx::string
using RuntimeName_t = cxx::string<MAX_RUNTIME_NAME_LENGTH>;
using NodeName_t = cxx::string<100>;
using ShmName_t = cxx::string<128>;

namespace capro
{
using IdString_t = cxx::string<100>;
}

/// @todo Move everything in this namespace to iceoryx_roudi_types.hpp once we move RouDi to a separate CMake target
namespace roudi
{
using ConfigFilePathString_t = cxx::string<1024>;

constexpr const char ROUDI_LOCK_NAME[] = "iox-unique-roudi";
constexpr const char IPC_CHANNEL_ROUDI_NAME[] = "roudi";

/// shared memmory segment for the iceoryx managment data
constexpr const char SHM_NAME[] = "iceoryx_mgmt";

// this is used by the UniquePortId
constexpr uint16_t DEFAULT_UNIQUE_ROUDI_ID{0U};

// Timeout
using namespace units::duration_literals;
constexpr units::Duration PROCESS_DEFAULT_KILL_DELAY = 45_s;
constexpr units::Duration PROCESS_TERMINATED_CHECK_INTERVAL = 250_ms;
constexpr units::Duration DISCOVERY_INTERVAL = 100_ms;

/// @brief Controls process alive monitoring. Upon timeout, a monitored process is removed
/// and its resources are made available. The process can then start and register itself again.
/// Contrarily, unmonitored processes can be restarted but registration will fail.
/// Once Runlevel Management is extended, it will detect absent processes. Those processes can register again.
/// ON - all processes are monitored
/// OFF - no process is monitored
enum class MonitoringMode
{
    ON,
    OFF
};

iox::log::LogStream& operator<<(iox::log::LogStream& logstream, const MonitoringMode& mode) noexcept;
} // namespace roudi

namespace mepoo
{
using SequenceNumber_t = std::uint64_t;
using BaseClock_t = std::chrono::steady_clock;

// use signed integer for duration;
// there is a bug in gcc 4.8 which leads to a wrong calcutated time
// when sleep_until() is used with a timepoint in the past
using DurationNs_t = std::chrono::duration<std::int64_t, std::nano>;
using TimePointNs_t = std::chrono::time_point<BaseClock_t, DurationNs_t>;
} // namespace mepoo

namespace runtime
{
using ServiceContainer = iox::cxx::vector<capro::ServiceDescription, MAX_NUMBER_OF_SERVICES>;
using namespace units::duration_literals;
constexpr units::Duration PROCESS_WAITING_FOR_ROUDI_TIMEOUT = 60_s;
constexpr units::Duration PROCESS_KEEP_ALIVE_INTERVAL = 3 * roudi::DISCOVERY_INTERVAL;  // > DISCOVERY_INTERVAL
constexpr units::Duration PROCESS_KEEP_ALIVE_TIMEOUT = 5 * PROCESS_KEEP_ALIVE_INTERVAL; // > PROCESS_KEEP_ALIVE_INTERVAL
} // namespace runtime

namespace version
{
static const uint64_t COMMIT_ID_STRING_SIZE = 12u;
using CommitIdString_t = cxx::string<COMMIT_ID_STRING_SIZE>;
static const uint64_t BUILD_DATE_STRING_SIZE = 36u;
using BuildDateString_t = cxx::string<BUILD_DATE_STRING_SIZE>;
} // namespace version

} // namespace iox

#include "iceoryx_posh/iceoryx_posh_types.inl"

#endif // IOX_POSH_ICEORYX_POSH_TYPES_HPP
<|endoftext|>


<commit_before>/*********************************************************************************
* Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Rob McDonald - initial code and implementation
********************************************************************************/

#ifndef eli_geom_intersect_intersect_surface_surface_hpp
#define eli_geom_intersect_intersect_surface_surface_hpp

#include <cmath>
#include <vector>
#include <list>
#include <algorithm>

#include "eli/code_eli.hpp"

#include "eli/mutil/nls/newton_raphson_method.hpp"

#include "eli/geom/point/distance.hpp"
#include "eli/geom/curve/piecewise.hpp"
#include "eli/geom/intersect/minimum_distance_bounding_box.hpp"

namespace eli
{
  namespace geom
  {
    namespace intersect
    {
      namespace internal
      {
        template <typename surface__>
        struct surf_surf_g_functor
        {
          const surface__ *s1;
          const surface__ *s2;
          typename surface__::point_type pt;

          typedef typename Eigen::Matrix<typename surface__::data_type, 4, 1> vec;

          vec operator()(const vec &x) const
          {
            typename surface__::data_type u1(x[0]), v1(x[1]);
            typename surface__::data_type u2(x[2]), v2(x[3]);
            vec rtn;

            typename surface__::data_type u1min, u1max, v1min, v1max;
            typename surface__::data_type u2min, u2max, v2min, v2max;

            s1->get_parameter_min(u1min,v1min);
            s1->get_parameter_max(u1max,v1max);
            s2->get_parameter_min(u2min,v2min);
            s2->get_parameter_max(u2max,v2max);

            u1=std::min(std::max(u1, u1min), u1max);
            v1=std::min(std::max(v1, v1min), v1max);
            u2=std::min(std::max(u2, u2min), u2max);
            v2=std::min(std::max(v2, v2min), v2max);

            typename surface__::point_type p1, p2, pave, disp, tvec;

            p1=s1->f(u1,v1);
            p2=s2->f(u2,v2);

            pave=(p1+p2)*0.5;
            disp=p2-p1;

            tvec=(s1->f_u(u1,v1).cross(s1->f_v(u1,v1))).cross(s2->f_u(u2,v2).cross(s2->f_v(u2,v2)));

            rtn(0)=disp(0);
            rtn(1)=disp(1);
            rtn(2)=disp(2);
            rtn(3)=tvec.dot(pave-pt);
            return rtn;
          }
        };

        template <typename surface__>
        struct surf_surf_gp_functor
        {
          const surface__ *s1;
          const surface__ *s2;
          typename surface__::point_type pt;

          typedef typename Eigen::Matrix<typename surface__::data_type, 4, 1> vec;
          typedef typename Eigen::Matrix<typename surface__::data_type, 4, 4> mat;

          mat operator()(const vec &x) const
          {
            typename surface__::data_type u1(x[0]), v1(x[1]);
            typename surface__::data_type u2(x[2]), v2(x[3]);
            mat rtn;

            typename surface__::data_type u1min, u1max, v1min, v1max;
            typename surface__::data_type u2min, u2max, v2min, v2max;

            s1->get_parameter_min(u1min,v1min);
            s1->get_parameter_max(u1max,v1max);
            s2->get_parameter_min(u2min,v2min);
            s2->get_parameter_max(u2max,v2max);

            u1=std::min(std::max(u1, u1min), u1max);
            v1=std::min(std::max(v1, v1min), v1max);
            u2=std::min(std::max(u2, u2min), u2max);
            v2=std::min(std::max(v2, v2min), v2max);

            typename surface__::point_type S1u, S1v, S1uu, S1uv, S1vv;
            typename surface__::point_type S2u, S2v, S2uu, S2uv, S2vv;

            typename surface__::point_type p1, p2, pave, tvec, dist;

            p1=s1->f(u1,v1);
            p2=s2->f(u2,v2);

            pave=(p1+p2)*0.5;
            dist=pave-pt;

            S1u=s1->f_u(u1, v1);
            S1v=s1->f_v(u1, v1);
            S1uu=s1->f_uu(u1, v1);
            S1uv=s1->f_uv(u1, v1);
            S1vv=s1->f_vv(u1, v1);

            S2u=s2->f_u(u2, v2);
            S2v=s2->f_v(u2, v2);
            S2uu=s2->f_uu(u2, v2);
            S2uv=s2->f_uv(u2, v2);
            S2vv=s2->f_vv(u2, v2);

            tvec=(S1u.cross(S1v)).cross(S2u.cross(S2v));

            rtn(0,0)=-S1u(0);
            rtn(0,1)=-S1v(0);
            rtn(0,2)=S2u(0);
            rtn(0,3)=S2v(0);

            rtn(1,0)=-S1u(1);
            rtn(1,1)=-S1v(1);
            rtn(1,2)=S2u(1);
            rtn(1,3)=S2v(1);

            rtn(2,0)=-S1u(2);
            rtn(2,1)=-S1v(2);
            rtn(2,2)=S2u(2);
            rtn(2,3)=S2v(2);

            // tvec.dot(dist);

            rtn(3,0)= dist.dot( ( S1uu.cross(S1v)+S1u.cross(S1uv) ).cross(S2u.cross(S2v)) ) + tvec.dot( S1u * 0.5 );
            rtn(3,1)= dist.dot( ( S1uv.cross(S1v)+S1u.cross(S1vv) ).cross(S2u.cross(S2v)) ) + tvec.dot( S1v * 0.5 );
            rtn(3,2)= dist.dot( (S1u.cross(S1v)).cross( S2uu.cross(S2v)+S2u.cross(S2uv) ) ) + tvec.dot( S2u * 0.5 );
            rtn(3,3)= dist.dot( (S1u.cross(S1v)).cross( S2uv.cross(S2v)+S2u.cross(S2vv) ) ) + tvec.dot( S2v * 0.5 );

            // TODO: What to do if matrix becomes singular?

            return rtn;
          }
        };
      }

      template<typename surface__>
      typename surface__::data_type intersect(typename surface__::data_type &u1, typename surface__::data_type &v1,
                                              typename surface__::data_type &u2, typename surface__::data_type &v2,
                                              const surface__ &s1, const surface__ &s2, const typename surface__::point_type &pt,
                                              const typename surface__::data_type &u01, const typename surface__::data_type &v01,
                                              const typename surface__::data_type &u02, const typename surface__::data_type &v02 )
      {
        typedef eli::mutil::nls::newton_raphson_system_method<typename surface__::data_type, 4, 1> nonlinear_solver_type;
        nonlinear_solver_type nrm;
        internal::surf_surf_g_functor<surface__> g;
        internal::surf_surf_gp_functor<surface__> gp;
        typename surface__::data_type dist0, dist;
        typename surface__::tolerance_type tol;

        typename surface__::data_type u1min, u1max, v1min, v1max;
        typename surface__::data_type u2min, u2max, v2min, v2max;

        s1.get_parameter_min(u1min,v1min);
        s1.get_parameter_max(u1max,v1max);
        s2.get_parameter_min(u2min,v2min);
        s2.get_parameter_max(u2max,v2max);

        typename surface__::point_type p1, p2;

        p1=s1.f(u01,v01);
        p2=s2.f(u02,v02);

        // setup the functors
        g.s1=&s1;
        g.s2=&s2;
        g.pt=pt;
        gp.s1=&s1;
        gp.s2=&s2;
        gp.pt=pt;

        // setup the solver
        nrm.set_absolute_f_tolerance(tol.get_absolute_tolerance());
        nrm.set_max_iteration(20);
        nrm.set_norm_type(nonlinear_solver_type::max_norm);

        if (s1.open_u())
        {
          nrm.set_lower_condition(0, u1min, nonlinear_solver_type::IRC_EXCLUSIVE);
          nrm.set_upper_condition(0, u1max, nonlinear_solver_type::IRC_EXCLUSIVE);
        }
        else
        {
          nrm.set_periodic_condition(0, u1min, u1max);
        }

        if (s1.open_v())
        {
          nrm.set_lower_condition(1, v1min, nonlinear_solver_type::IRC_EXCLUSIVE);
          nrm.set_upper_condition(1, v1max, nonlinear_solver_type::IRC_EXCLUSIVE);
        }
        else
        {
          nrm.set_periodic_condition(1, v1min, v1max);
        }

        if (s2.open_u())
        {
          nrm.set_lower_condition(2, u2min, nonlinear_solver_type::IRC_EXCLUSIVE);
          nrm.set_upper_condition(2, u2max, nonlinear_solver_type::IRC_EXCLUSIVE);
        }
        else
        {
          nrm.set_periodic_condition(2, u2min, u2max);
        }

        if (s2.open_v())
        {
          nrm.set_lower_condition(3, v2min, nonlinear_solver_type::IRC_EXCLUSIVE);
          nrm.set_upper_condition(3, v2max, nonlinear_solver_type::IRC_EXCLUSIVE);
        }
        else
        {
          nrm.set_periodic_condition(3, v2min, v2max);
        }

        // set the initial guess
        typename nonlinear_solver_type::solution_matrix xinit, rhs, ans;

        xinit(0)=u01;
        xinit(1)=v01;
        xinit(2)=u02;
        xinit(3)=v02;
        nrm.set_initial_guess(xinit);
        rhs.setZero();

        dist0=eli::geom::point::distance(p1, p2);

        // find the root
        nrm.find_root(ans, g, gp, rhs);
        u1=ans(0);
        v1=ans(1);
        u2=ans(2);
        v2=ans(3);

        // if root is within bounds and is closer than initial guess
        assert((u>=umin) && (u<=umax));
        assert((v>=vmin) && (v<=vmax));

        dist = eli::geom::point::distance(s1.f(u1, v1), s2.f(u2,v2));

//        if( dist > 1e-6 )
//        {
//          printf("d0: %g d: %g\n", dist0, dist );
//          printf(" u01: %f u1: %f\n", u01, u1 );
//          printf(" v01: %f v1: %f\n", v01, v1 );
//          printf(" u02: %f u2: %f\n", u02, u2 );
//          printf(" v02: %f v2: %f\n", v02, v2 );
//        }

        if  (dist<=dist0)
        {
          return dist;
        }

        // couldn't find better answer so return initial guess
        u1=u01;
        v1=v01;
        u2=u02;
        v2=v02;
        return dist0;
      }

    }
  }
}
#endif
<commit_msg>Removes Assert Statements for Undefined Variables<commit_after>/*********************************************************************************
* Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Rob McDonald - initial code and implementation
********************************************************************************/

#ifndef eli_geom_intersect_intersect_surface_surface_hpp
#define eli_geom_intersect_intersect_surface_surface_hpp

#include <cmath>
#include <vector>
#include <list>
#include <algorithm>

#include "eli/code_eli.hpp"

#include "eli/mutil/nls/newton_raphson_method.hpp"

#include "eli/geom/point/distance.hpp"
#include "eli/geom/curve/piecewise.hpp"
#include "eli/geom/intersect/minimum_distance_bounding_box.hpp"

namespace eli
{
  namespace geom
  {
    namespace intersect
    {
      namespace internal
      {
        template <typename surface__>
        struct surf_surf_g_functor
        {
          const surface__ *s1;
          const surface__ *s2;
          typename surface__::point_type pt;

          typedef typename Eigen::Matrix<typename surface__::data_type, 4, 1> vec;

          vec operator()(const vec &x) const
          {
            typename surface__::data_type u1(x[0]), v1(x[1]);
            typename surface__::data_type u2(x[2]), v2(x[3]);
            vec rtn;

            typename surface__::data_type u1min, u1max, v1min, v1max;
            typename surface__::data_type u2min, u2max, v2min, v2max;

            s1->get_parameter_min(u1min,v1min);
            s1->get_parameter_max(u1max,v1max);
            s2->get_parameter_min(u2min,v2min);
            s2->get_parameter_max(u2max,v2max);

            u1=std::min(std::max(u1, u1min), u1max);
            v1=std::min(std::max(v1, v1min), v1max);
            u2=std::min(std::max(u2, u2min), u2max);
            v2=std::min(std::max(v2, v2min), v2max);

            typename surface__::point_type p1, p2, pave, disp, tvec;

            p1=s1->f(u1,v1);
            p2=s2->f(u2,v2);

            pave=(p1+p2)*0.5;
            disp=p2-p1;

            tvec=(s1->f_u(u1,v1).cross(s1->f_v(u1,v1))).cross(s2->f_u(u2,v2).cross(s2->f_v(u2,v2)));

            rtn(0)=disp(0);
            rtn(1)=disp(1);
            rtn(2)=disp(2);
            rtn(3)=tvec.dot(pave-pt);
            return rtn;
          }
        };

        template <typename surface__>
        struct surf_surf_gp_functor
        {
          const surface__ *s1;
          const surface__ *s2;
          typename surface__::point_type pt;

          typedef typename Eigen::Matrix<typename surface__::data_type, 4, 1> vec;
          typedef typename Eigen::Matrix<typename surface__::data_type, 4, 4> mat;

          mat operator()(const vec &x) const
          {
            typename surface__::data_type u1(x[0]), v1(x[1]);
            typename surface__::data_type u2(x[2]), v2(x[3]);
            mat rtn;

            typename surface__::data_type u1min, u1max, v1min, v1max;
            typename surface__::data_type u2min, u2max, v2min, v2max;

            s1->get_parameter_min(u1min,v1min);
            s1->get_parameter_max(u1max,v1max);
            s2->get_parameter_min(u2min,v2min);
            s2->get_parameter_max(u2max,v2max);

            u1=std::min(std::max(u1, u1min), u1max);
            v1=std::min(std::max(v1, v1min), v1max);
            u2=std::min(std::max(u2, u2min), u2max);
            v2=std::min(std::max(v2, v2min), v2max);

            typename surface__::point_type S1u, S1v, S1uu, S1uv, S1vv;
            typename surface__::point_type S2u, S2v, S2uu, S2uv, S2vv;

            typename surface__::point_type p1, p2, pave, tvec, dist;

            p1=s1->f(u1,v1);
            p2=s2->f(u2,v2);

            pave=(p1+p2)*0.5;
            dist=pave-pt;

            S1u=s1->f_u(u1, v1);
            S1v=s1->f_v(u1, v1);
            S1uu=s1->f_uu(u1, v1);
            S1uv=s1->f_uv(u1, v1);
            S1vv=s1->f_vv(u1, v1);

            S2u=s2->f_u(u2, v2);
            S2v=s2->f_v(u2, v2);
            S2uu=s2->f_uu(u2, v2);
            S2uv=s2->f_uv(u2, v2);
            S2vv=s2->f_vv(u2, v2);

            tvec=(S1u.cross(S1v)).cross(S2u.cross(S2v));

            rtn(0,0)=-S1u(0);
            rtn(0,1)=-S1v(0);
            rtn(0,2)=S2u(0);
            rtn(0,3)=S2v(0);

            rtn(1,0)=-S1u(1);
            rtn(1,1)=-S1v(1);
            rtn(1,2)=S2u(1);
            rtn(1,3)=S2v(1);

            rtn(2,0)=-S1u(2);
            rtn(2,1)=-S1v(2);
            rtn(2,2)=S2u(2);
            rtn(2,3)=S2v(2);

            // tvec.dot(dist);

            rtn(3,0)= dist.dot( ( S1uu.cross(S1v)+S1u.cross(S1uv) ).cross(S2u.cross(S2v)) ) + tvec.dot( S1u * 0.5 );
            rtn(3,1)= dist.dot( ( S1uv.cross(S1v)+S1u.cross(S1vv) ).cross(S2u.cross(S2v)) ) + tvec.dot( S1v * 0.5 );
            rtn(3,2)= dist.dot( (S1u.cross(S1v)).cross( S2uu.cross(S2v)+S2u.cross(S2uv) ) ) + tvec.dot( S2u * 0.5 );
            rtn(3,3)= dist.dot( (S1u.cross(S1v)).cross( S2uv.cross(S2v)+S2u.cross(S2vv) ) ) + tvec.dot( S2v * 0.5 );

            // TODO: What to do if matrix becomes singular?

            return rtn;
          }
        };
      }

      template<typename surface__>
      typename surface__::data_type intersect(typename surface__::data_type &u1, typename surface__::data_type &v1,
                                              typename surface__::data_type &u2, typename surface__::data_type &v2,
                                              const surface__ &s1, const surface__ &s2, const typename surface__::point_type &pt,
                                              const typename surface__::data_type &u01, const typename surface__::data_type &v01,
                                              const typename surface__::data_type &u02, const typename surface__::data_type &v02 )
      {
        typedef eli::mutil::nls::newton_raphson_system_method<typename surface__::data_type, 4, 1> nonlinear_solver_type;
        nonlinear_solver_type nrm;
        internal::surf_surf_g_functor<surface__> g;
        internal::surf_surf_gp_functor<surface__> gp;
        typename surface__::data_type dist0, dist;
        typename surface__::tolerance_type tol;

        typename surface__::data_type u1min, u1max, v1min, v1max;
        typename surface__::data_type u2min, u2max, v2min, v2max;

        s1.get_parameter_min(u1min,v1min);
        s1.get_parameter_max(u1max,v1max);
        s2.get_parameter_min(u2min,v2min);
        s2.get_parameter_max(u2max,v2max);

        typename surface__::point_type p1, p2;

        p1=s1.f(u01,v01);
        p2=s2.f(u02,v02);

        // setup the functors
        g.s1=&s1;
        g.s2=&s2;
        g.pt=pt;
        gp.s1=&s1;
        gp.s2=&s2;
        gp.pt=pt;

        // setup the solver
        nrm.set_absolute_f_tolerance(tol.get_absolute_tolerance());
        nrm.set_max_iteration(20);
        nrm.set_norm_type(nonlinear_solver_type::max_norm);

        if (s1.open_u())
        {
          nrm.set_lower_condition(0, u1min, nonlinear_solver_type::IRC_EXCLUSIVE);
          nrm.set_upper_condition(0, u1max, nonlinear_solver_type::IRC_EXCLUSIVE);
        }
        else
        {
          nrm.set_periodic_condition(0, u1min, u1max);
        }

        if (s1.open_v())
        {
          nrm.set_lower_condition(1, v1min, nonlinear_solver_type::IRC_EXCLUSIVE);
          nrm.set_upper_condition(1, v1max, nonlinear_solver_type::IRC_EXCLUSIVE);
        }
        else
        {
          nrm.set_periodic_condition(1, v1min, v1max);
        }

        if (s2.open_u())
        {
          nrm.set_lower_condition(2, u2min, nonlinear_solver_type::IRC_EXCLUSIVE);
          nrm.set_upper_condition(2, u2max, nonlinear_solver_type::IRC_EXCLUSIVE);
        }
        else
        {
          nrm.set_periodic_condition(2, u2min, u2max);
        }

        if (s2.open_v())
        {
          nrm.set_lower_condition(3, v2min, nonlinear_solver_type::IRC_EXCLUSIVE);
          nrm.set_upper_condition(3, v2max, nonlinear_solver_type::IRC_EXCLUSIVE);
        }
        else
        {
          nrm.set_periodic_condition(3, v2min, v2max);
        }

        // set the initial guess
        typename nonlinear_solver_type::solution_matrix xinit, rhs, ans;

        xinit(0)=u01;
        xinit(1)=v01;
        xinit(2)=u02;
        xinit(3)=v02;
        nrm.set_initial_guess(xinit);
        rhs.setZero();

        dist0=eli::geom::point::distance(p1, p2);

        // find the root
        nrm.find_root(ans, g, gp, rhs);
        u1=ans(0);
        v1=ans(1);
        u2=ans(2);
        v2=ans(3);

        dist = eli::geom::point::distance(s1.f(u1, v1), s2.f(u2,v2));

//        if( dist > 1e-6 )
//        {
//          printf("d0: %g d: %g\n", dist0, dist );
//          printf(" u01: %f u1: %f\n", u01, u1 );
//          printf(" v01: %f v1: %f\n", v01, v1 );
//          printf(" u02: %f u2: %f\n", u02, u2 );
//          printf(" v02: %f v2: %f\n", v02, v2 );
//        }

        if  (dist<=dist0)
        {
          return dist;
        }

        // couldn't find better answer so return initial guess
        u1=u01;
        v1=v01;
        u2=u02;
        v2=v02;
        return dist0;
      }

    }
  }
}
#endif
<|endoftext|>