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

#include <vcl/metric.hxx>
#include <svx/outliner.hxx>
#include <svx/svdorect.hxx>
#include <svx/svdoutl.hxx>
#include <svx/svxfont.hxx>
#include "drawdoc.hxx"
#include "outlinfo.hxx"

// ----------------
// - OutlinerInfo -
// ----------------

OutlinerInfo::OutlinerInfo() :
            pParagraphs ( NULL ),
            nParaCount  ( 0UL ),
            nExtraData  ( 0L )
{
}

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

OutlinerInfo::~OutlinerInfo()
{
    Clear();
}

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

void OutlinerInfo::SetTextObj( SdDrawDocument* pDoc, SdrRectObj* pObj, OutputDevice* _pOut )
{
    Clear();

    SdrOutliner& rOutliner = pDoc->GetDrawOutliner();

    pOut = _pOut;
    rOutliner.SetText( *pObj->GetOutlinerParaObject() );

    aObjBound = pObj->GetBoundRect();
    nParaCount = rOutliner.GetParagraphCount();
    nExtraData = 0L;

    if( nParaCount )
    {
        mbVertical = rOutliner.IsVertical();
        pObj->TakeTextRect( rOutliner, aParaBound, TRUE );

        if(IsVertical())
            aTextOffset = aParaBound.TopRight();
        else
            aTextOffset = aParaBound.TopLeft();

        nCurPara = 0;
        bInit = TRUE;

        rOutliner.SetDrawPortionHdl( LINK( this, OutlinerInfo, DrawPortionHdl ) );
        pParagraphs = new OutlinerParagraph[ nParaCount ];
        rOutliner.StripPortions();
        rOutliner.SetDrawPortionHdl( Link() );

        // letzter Absatz
        pParagraphs[ nCurPara ].aRect.Bottom() = aParaBound.Bottom();
    }
    else
    {
        pParagraphs = NULL;
        aParaBound = Rectangle();
        aTextOffset = Point();
    }

    nCurPara = 0;
    bInit = FALSE;
}

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

void OutlinerInfo::Clear()
{
    for( void* pChar = aCharacterList.First(); pChar; pChar = aCharacterList.Next() )
        delete (OutlinerCharacter*) pChar;
    aCharacterList.Clear();

    delete[] pParagraphs;
    pParagraphs = NULL;

    nCurPara = nParaCount = 0UL;
    aObjBound = aParaBound = Rectangle();
    aTextOffset = Point();
}

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

const Rectangle& OutlinerInfo::GetParaRect( const ULONG nPara ) const
{
    DBG_ASSERT( nPara < nParaCount, "Para out of range!" );
    return pParagraphs[ nPara ].aRect;
}

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

BOOL OutlinerInfo::GetParaCharCount( const ULONG nPara ) const
{
    DBG_ASSERT( nPara < nParaCount, "Para out of range!" );
    return (0 != pParagraphs[ nPara ].nCharCount);
}

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

IMPL_LINK( OutlinerInfo, DrawPortionHdl, DrawPortionInfo*, pDInfo )
{
    const USHORT    nCharCount = pDInfo->rText.Len();
    Point           aStart;

    pOut->SetFont( (const Font&) pDInfo->rFont );

    if(IsVertical())
    {
        aStart.X() = pDInfo->rStartPos.X() + aTextOffset.X() - pOut->GetFontMetric().GetDescent();
        aStart.Y() = pDInfo->rStartPos.Y() + aTextOffset.Y();

        if( bInit )
        {
            pParagraphs[ 0 ].aRect = aParaBound;
            bInit = FALSE;
        }
        else if( pDInfo->nPara != nCurPara )
        {
            pParagraphs[ nCurPara = pDInfo->nPara ].aRect = Rectangle( aParaBound.Left(), aStart.Y(),
                aTextOffset.X() + pDInfo->rStartPos.X() + pOut->GetFontMetric().GetAscent(),
                aParaBound.Bottom() );

            Point aPt1Pix( pOut->LogicToPixel( pParagraphs[ nCurPara - 1 ].aRect.TopRight() ) );
            Point aPt2Pix( pOut->LogicToPixel( pParagraphs[ nCurPara ].aRect.TopRight() ) );
            Size aSizePix( pOut->PixelToLogic( Size( aPt1Pix.X() - aPt2Pix.X() + 1 , 0 ) ) );
            pParagraphs[ nCurPara - 1 ].aRect = Rectangle(
                Point(pParagraphs[ nCurPara - 1 ].aRect.TopRight().X() - aSizePix.Width() , pParagraphs[ nCurPara - 1 ].aRect.TopRight().Y()),
                Size(aSizePix.Width(), pParagraphs[ nCurPara - 1 ].aRect.GetHeight()));
        }
        else if( aStart.X() >= pParagraphs[ nCurPara ].aRect.Right() )
        {
            pParagraphs[ nCurPara ].aRect.Right() = aStart.X();

            if( nCurPara )
            {
                Point aPt1Pix( pOut->LogicToPixel( pParagraphs[ nCurPara - 1 ].aRect.TopRight() ) );
                Point aPt2Pix( pOut->LogicToPixel( pParagraphs[ nCurPara ].aRect.TopRight() ) );
                Size aSizePix( pOut->PixelToLogic( Size( aPt1Pix.X() - aPt2Pix.X() + 1, 0 ) ) );
                pParagraphs[ nCurPara - 1 ].aRect = Rectangle(
                    Point(pParagraphs[ nCurPara - 1 ].aRect.TopRight().X() - aSizePix.Width() , pParagraphs[ nCurPara - 1 ].aRect.TopRight().Y()),
                    Size(aSizePix.Width(), pParagraphs[ nCurPara - 1 ].aRect.GetHeight()));
            }
        }

        if( nCharCount && ( pDInfo->nIndex != 0xFFFF ) )
        {
            pParagraphs[ nCurPara ].nCharCount += nCharCount;

            for( USHORT nCharIndex = 0; nCharIndex < nCharCount; nCharIndex++ )
            {
                Size aCharSize(pDInfo->rFont.GetPhysTxtSize( pOut, pDInfo->rText, nCharIndex, 1 ));
                Size aMirroredCharSize(aCharSize.Height(), aCharSize.Width());
                const Rectangle aRect( aStart, aMirroredCharSize );

                aCharacterList.Insert( new OutlinerCharacter( aRect, pDInfo->nPara,
                                                              pDInfo->rFont.GetColor(),
                                                              pDInfo->rText.GetChar( nCharIndex ) ), LIST_APPEND );

                if( nCharIndex < nCharCount - 1 )
                    aStart.Y() = pDInfo->rStartPos.Y() + aTextOffset.Y() + ( pDInfo->pDXArray )[ nCharIndex ];
            }
        }
    }
    else
    {
        aStart.X() = pDInfo->rStartPos.X() + aTextOffset.X();
        aStart.Y() = pDInfo->rStartPos.Y() + aTextOffset.Y() - pOut->GetFontMetric().GetAscent();

        if( bInit )
        {
            pParagraphs[ 0 ].aRect = aParaBound;
            bInit = FALSE;
        }
        else if( pDInfo->nPara != nCurPara )
        {
            pParagraphs[ nCurPara = pDInfo->nPara ].aRect = Rectangle( aStart.X(), aStart.Y(), aParaBound.Right(), aParaBound.Bottom() );

            Point aPt1Pix( pOut->LogicToPixel( pParagraphs[ nCurPara - 1 ].aRect.TopLeft() ) );
            Point aPt2Pix( pOut->LogicToPixel( pParagraphs[ nCurPara ].aRect.TopLeft() ) );
            Size aSizePix( pOut->PixelToLogic( Size( 0, aPt2Pix.Y() - aPt1Pix.Y() + 1 ) ) );
            pParagraphs[ nCurPara - 1 ].aRect.SetSize( Size( pParagraphs[ nCurPara - 1 ].aRect.GetWidth(), aSizePix.Height() ) );
        }
        else if( aStart.Y() < pParagraphs[ nCurPara ].aRect.Top() )
        {
            pParagraphs[ nCurPara ].aRect.Top() = aStart.Y();

            if( nCurPara )
            {
                Point aPt1Pix( pOut->LogicToPixel( pParagraphs[ nCurPara - 1 ].aRect.TopLeft() ) );
                Point aPt2Pix( pOut->LogicToPixel( pParagraphs[ nCurPara ].aRect.TopLeft() ) );
                Size aSizePix( pOut->PixelToLogic( Size( 0, aPt2Pix.Y() - aPt1Pix.Y() + 1 ) ) );
                pParagraphs[ nCurPara - 1 ].aRect.SetSize( Size( pParagraphs[ nCurPara - 1 ].aRect.GetWidth(), aSizePix.Height() ) );
            }
        }

        if( nCharCount && ( pDInfo->nIndex != 0xFFFF ) )
        {
            pParagraphs[ nCurPara ].nCharCount += nCharCount;

            for( USHORT nCharIndex = 0; nCharIndex < nCharCount; nCharIndex++ )
            {
                const Rectangle aRect( aStart, pDInfo->rFont.GetPhysTxtSize( pOut, pDInfo->rText, nCharIndex, 1 ) );

                aCharacterList.Insert( new OutlinerCharacter( aRect, pDInfo->nPara,
                                                              pDInfo->rFont.GetColor(),
                                                              pDInfo->rText.GetChar( nCharIndex ) ), LIST_APPEND );

                if( nCharIndex < nCharCount - 1 )
                    aStart.X() = pDInfo->rStartPos.X() + aTextOffset.X() + ( pDInfo->pDXArray )[ nCharIndex ];
            }
        }
    }

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

#include <vcl/metric.hxx>
#include <svx/outliner.hxx>
#include <svx/svdorect.hxx>
#include <svx/svdoutl.hxx>
#include <svx/svxfont.hxx>
#include "drawdoc.hxx"
#include "outlinfo.hxx"

// ----------------
// - OutlinerInfo -
// ----------------

OutlinerInfo::OutlinerInfo() :
            pParagraphs ( NULL ),
            nParaCount  ( 0UL ),
            nExtraData  ( 0L )
{
}

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

OutlinerInfo::~OutlinerInfo()
{
    Clear();
}

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

void OutlinerInfo::SetTextObj( SdDrawDocument* pDoc, SdrRectObj* pObj, OutputDevice* _pOut )
{
    Clear();

    SdrOutliner& rOutliner = pDoc->GetDrawOutliner();

    pOut = _pOut;
    rOutliner.SetText( *pObj->GetOutlinerParaObject() );

    aObjBound = pObj->GetBoundRect();
    nParaCount = rOutliner.GetParagraphCount();
    nExtraData = 0L;

    if( nParaCount )
    {
        mbVertical = rOutliner.IsVertical();
        pObj->TakeTextRect( rOutliner, aParaBound, TRUE );

        if(IsVertical())
            aTextOffset = aParaBound.TopRight();
        else
            aTextOffset = aParaBound.TopLeft();

        nCurPara = 0;
        bInit = TRUE;

        rOutliner.SetDrawPortionHdl( LINK( this, OutlinerInfo, DrawPortionHdl ) );
        pParagraphs = new OutlinerParagraph[ nParaCount ];
        rOutliner.StripPortions();
        rOutliner.SetDrawPortionHdl( Link() );

        // letzter Absatz
        pParagraphs[ nCurPara ].aRect.Bottom() = aParaBound.Bottom();
    }
    else
    {
        pParagraphs = NULL;
        aParaBound = Rectangle();
        aTextOffset = Point();
    }

    nCurPara = 0;
    bInit = FALSE;
}

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

void OutlinerInfo::Clear()
{
    for( void* pChar = aCharacterList.First(); pChar; pChar = aCharacterList.Next() )
        delete (OutlinerCharacter*) pChar;
    aCharacterList.Clear();

    delete[] pParagraphs;
    pParagraphs = NULL;

    nCurPara = nParaCount = 0UL;
    aObjBound = aParaBound = Rectangle();
    aTextOffset = Point();
}

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

const Rectangle& OutlinerInfo::GetParaRect( const ULONG nPara ) const
{
    DBG_ASSERT( nPara < nParaCount, "Para out of range!" );
    return pParagraphs[ nPara ].aRect;
}

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

BOOL OutlinerInfo::GetParaCharCount( const ULONG nPara ) const
{
    DBG_ASSERT( nPara < nParaCount, "Para out of range!" );
    return (0 != pParagraphs[ nPara ].nCharCount);
}

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

IMPL_LINK( OutlinerInfo, DrawPortionHdl, DrawPortionInfo*, pDInfo )
{
    const USHORT    nCharCount = pDInfo->rText.Len();
    Point           aStart;

    pOut->SetFont( (const Font&) pDInfo->rFont );

    if(IsVertical())
    {
        // get upper left position
        aStart.X() = pDInfo->rStartPos.X() + aTextOffset.X() - pOut->GetFontMetric().GetDescent();
        aStart.Y() = pDInfo->rStartPos.Y() + aTextOffset.Y();

        if(bInit || pDInfo->nPara != nCurPara)
        {
            // new paragraph started. Init new rectangle.
            if(bInit)
                bInit = FALSE;
            else
                nCurPara = pDInfo->nPara;

            Rectangle aNewRect(
                aStart.X(), aParaBound.Top(),
                aStart.X() + pOut->GetFontMetric().GetLineHeight(), aParaBound.Bottom());
            pParagraphs[nCurPara].aRect = aNewRect;
        }
        else
        {
            // new text portion in current paragraph. Calc min and max
            // positions and compare to current rectangle.
            sal_Int32 nMin = aStart.X();
            sal_Int32 nMax = aStart.X() + pOut->GetFontMetric().GetLineHeight();

            if(nMin < pParagraphs[nCurPara].aRect.Left())
            {
                // correct left edge of current para
                pParagraphs[nCurPara].aRect.Left() = nMin;
            }

            if(nMax > pParagraphs[nCurPara].aRect.Right())
            {
                // correct right edge of current para
                pParagraphs[nCurPara].aRect.Right() = nMax;
            }
        }

        // get character rectangles
        if(nCharCount && (0xFFFF != pDInfo->nIndex))
        {
            // add this portions char count
            pParagraphs[nCurPara].nCharCount += nCharCount;

            for(sal_uInt16 nCharIndex(0); nCharIndex < nCharCount; nCharIndex++)
            {
                Size aCharSize(pDInfo->rFont.GetPhysTxtSize(pOut, pDInfo->rText, nCharIndex, 1));
                Size aMirroredCharSize(aCharSize.Height(), aCharSize.Width());
                const Rectangle aRect(aStart, aMirroredCharSize);
                aCharacterList.Insert(new OutlinerCharacter(
                    aRect, pDInfo->nPara, pDInfo->rFont.GetColor(),
                    pDInfo->rText.GetChar( nCharIndex ) ), LIST_APPEND);

                if(nCharIndex < nCharCount-1)
                    aStart.Y() = pDInfo->rStartPos.Y() + aTextOffset.Y() + (pDInfo->pDXArray)[nCharIndex];
            }
        }
    }
    else
    {
        aStart.X() = pDInfo->rStartPos.X() + aTextOffset.X();
        aStart.Y() = pDInfo->rStartPos.Y() + aTextOffset.Y() - pOut->GetFontMetric().GetAscent();

        if( bInit )
        {
            pParagraphs[ 0 ].aRect = aParaBound;
            bInit = FALSE;
        }
        else if( pDInfo->nPara != nCurPara )
        {
            pParagraphs[ nCurPara = pDInfo->nPara ].aRect = Rectangle( aStart.X(), aStart.Y(), aParaBound.Right(), aParaBound.Bottom() );

            Point aPt1Pix( pOut->LogicToPixel( pParagraphs[ nCurPara - 1 ].aRect.TopLeft() ) );
            Point aPt2Pix( pOut->LogicToPixel( pParagraphs[ nCurPara ].aRect.TopLeft() ) );
            Size aSizePix( pOut->PixelToLogic( Size( 0, aPt2Pix.Y() - aPt1Pix.Y() + 1 ) ) );
            pParagraphs[ nCurPara - 1 ].aRect.SetSize( Size( pParagraphs[ nCurPara - 1 ].aRect.GetWidth(), aSizePix.Height() ) );
        }
        else if( aStart.Y() < pParagraphs[ nCurPara ].aRect.Top() )
        {
            pParagraphs[ nCurPara ].aRect.Top() = aStart.Y();

            if( nCurPara )
            {
                Point aPt1Pix( pOut->LogicToPixel( pParagraphs[ nCurPara - 1 ].aRect.TopLeft() ) );
                Point aPt2Pix( pOut->LogicToPixel( pParagraphs[ nCurPara ].aRect.TopLeft() ) );
                Size aSizePix( pOut->PixelToLogic( Size( 0, aPt2Pix.Y() - aPt1Pix.Y() + 1 ) ) );
                pParagraphs[ nCurPara - 1 ].aRect.SetSize( Size( pParagraphs[ nCurPara - 1 ].aRect.GetWidth(), aSizePix.Height() ) );
            }
        }

        if( nCharCount && ( pDInfo->nIndex != 0xFFFF ) )
        {
            pParagraphs[ nCurPara ].nCharCount += nCharCount;

            for( USHORT nCharIndex = 0; nCharIndex < nCharCount; nCharIndex++ )
            {
                const Rectangle aRect( aStart, pDInfo->rFont.GetPhysTxtSize( pOut, pDInfo->rText, nCharIndex, 1 ) );

                aCharacterList.Insert( new OutlinerCharacter( aRect, pDInfo->nPara,
                                                              pDInfo->rFont.GetColor(),
                                                              pDInfo->rText.GetChar( nCharIndex ) ), LIST_APPEND );

                if( nCharIndex < nCharCount - 1 )
                    aStart.X() = pDInfo->rStartPos.X() + aTextOffset.X() + ( pDInfo->pDXArray )[ nCharIndex ];
            }
        }
    }

    return 0L;
}
<|endoftext|>


<commit_before>/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2009 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

#include "SDL.h"
#include "../../events/SDL_sysevents.h"
#include "../../events/SDL_events_c.h"

#include "SDL_pedigreevideo.h"
#include "SDL_pedigreeevents_c.h"

#include <syslog.h>

#include <input/Input.h>

// Input handler: receives input notifications and sends them to SDL
void input_handler(Input::InputNotification &note)
{
    if(note.type == Input::Key)
    {
        SDL_keysym sym;
        sym.scancode = 0;
        sym.sym = static_cast<SDLKey>(note.data.key.key);
        sym.mod = KMOD_NONE;
        sym.unicode = 0;
        SDL_PrivateKeyboard(SDL_PRESSED, &sym);
        SDL_PrivateKeyboard(SDL_RELEASED, &sym);
    }
    else if(note.type == Input::Mouse)
    {
        Uint8 state = 0;
        for(int i = 0; i < 8; i++)
            if(note.data.pointy.buttons[i])
                state |= (1 << i);

        SDL_PrivateMouseMotion(state, 1, (Sint16) note.data.pointy.relx, (Sint16) note.data.pointy.rely);
    }
}

void PEDIGREE_InitInput()
{
    Input::installCallback(Input::Key | Input::Mouse, input_handler);
}

void PEDIGREE_DestroyInput()
{
    Input::removeCallback(input_handler);
}

void PEDIGREE_PumpEvents(_THIS)
{
	// Nothing that has to be done here - everything comes in as events
}

void PEDIGREE_InitOSKeymap(_THIS)
{
	/// \todo Need to setup the keymap for stuff like the enter key!
}

<commit_msg>SDL: Input translation for arrow keys, buttons such as Home & End, and key modifiers. Fixes the #PF when you hit the arrow keys in an SDL app.<commit_after>/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997-2009 Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    Sam Lantinga
    slouken@libsdl.org
*/
#include "SDL_config.h"

#include "SDL.h"
#include "../../events/SDL_sysevents.h"
#include "../../events/SDL_events_c.h"

#include "SDL_pedigreevideo.h"
#include "SDL_pedigreeevents_c.h"

#include <syslog.h>

#include <input/Input.h>

namespace Keyboard
{
    enum KeyFlags
    {
        Special = 1ULL << 63,
        Ctrl    = 1ULL << 62,
        Shift   = 1ULL << 61,
        Alt     = 1ULL << 60,
        AltGr   = 1ULL << 59
    };
}

// Input handler: receives input notifications and sends them to SDL
void input_handler(Input::InputNotification &note)
{
    if(note.type == Input::Key)
    {
        uint64_t key = note.data.key.key;

        SDL_keysym sym;
        sym.scancode = 0;
        //sym.mod = KMOD_NONE;
        sym.unicode = 0;

        sym.mod = KMOD_NONE;
        if(key & Keyboard::Ctrl)
            sym.mod = static_cast<SDLMod>(sym.mod | KMOD_CTRL);
        if(key & Keyboard::Shift)
            sym.mod = static_cast<SDLMod>(sym.mod | KMOD_SHIFT);
        if(key & Keyboard::Alt)
            sym.mod = static_cast<SDLMod>(sym.mod | KMOD_ALT);
        if(key & Keyboard::AltGr)
            sym.mod = static_cast<SDLMod>(sym.mod | KMOD_META);

        SDLKey keySym = SDLK_UNKNOWN;
        if(key & Keyboard::Special)
        {
            char buf[5];
            memcpy(buf, static_cast<void*>(&key), 4);
            buf[4] = 0;

            if(!strcmp(buf, "left"))
                keySym = SDLK_LEFT;
            else if(!strcmp(buf, "righ"))
                keySym = SDLK_RIGHT;
            else if(!strcmp(buf, "up"))
                keySym = SDLK_UP;
            else if(!strcmp(buf, "down"))
                keySym = SDLK_DOWN;
            else if(!strcmp(buf, "ins"))
                keySym = SDLK_INSERT;
            else if(!strcmp(buf, "home"))
                keySym = SDLK_HOME;
            else if(!strcmp(buf, "end"))
                keySym = SDLK_END;
            else if(!strcmp(buf, "pgup"))
                keySym = SDLK_PAGEUP;
            else if(!strcmp(buf, "pgdn"))
                keySym = SDLK_PAGEDOWN;
        }
        else
            keySym = static_cast<SDLKey>(key);

        sym.sym = keySym;

        SDL_PrivateKeyboard(SDL_PRESSED, &sym);
        SDL_PrivateKeyboard(SDL_RELEASED, &sym);
    }
    else if(note.type == Input::Mouse)
    {
        Uint8 state = 0;
        for(int i = 0; i < 8; i++)
            if(note.data.pointy.buttons[i])
                state |= (1 << i);

        SDL_PrivateMouseMotion(state, 1, (Sint16) note.data.pointy.relx, (Sint16) note.data.pointy.rely);
    }
}

void PEDIGREE_InitInput()
{
    Input::installCallback(Input::Key | Input::Mouse, input_handler);
}

void PEDIGREE_DestroyInput()
{
    Input::removeCallback(input_handler);
}

void PEDIGREE_PumpEvents(_THIS)
{
	// Nothing that has to be done here - everything comes in as events
}

void PEDIGREE_InitOSKeymap(_THIS)
{
	/// \todo Need to setup the keymap for stuff like the enter key!
}

<|endoftext|>


<commit_before>#pragma once

#include <systemd/sd-bus.h>

#include <sdbusplus/bus.hpp>
#include <sdbusplus/sdbus.hpp>
#include <sdbusplus/slot.hpp>
#include <sdbusplus/vtable.hpp>

#include <string>

namespace sdbusplus
{

namespace server
{

namespace interface
{

/** @class interface
 *  @brief Provide a C++ holder for dbus interface instances.
 *
 *  Wraps sd_bus_add_object_vtable so that the interface is registered
 *  on construction and deregistered on destruction.
 *
 *  @note This class is 'final' because it is expected to be used by an
 *  implementation of a class representing a dbus interface, which will be
 *  composed through multiple-inheritence to create a single dbus 'object'.
 *  Marking it 'final' prevents users from using an 'is-a' relationship via
 *  inheritance, which might be a natural option.  Instead, a dbus interface
 *  implementation should 'has-a' server::interface with a name sufficiently
 *  unique to prevent name collisions in multiple-inheritence situations.
 */
struct interface final
{
    /* Define all of the basic class operations:
     *     Not allowed:
     *         - Default constructor to avoid nullptrs.
     *         - Copy operations due to internal unique_ptr.
     *         - Move operations.
     *     Allowed:
     *         - Destructor.
     */
    interface() = delete;
    interface(const interface&) = delete;
    interface& operator=(const interface&) = delete;
    interface(interface&&) = delete;
    interface& operator=(interface&&) = delete;

    /** @brief Register the (path, interface, vtable) as a dbus object.
     *
     *  @param[in] bus - The bus to register on.
     *  @param[in] path - The path to register as.
     *  @param[in] interf - The interface to register as.
     *  @param[in] vtable - The vtable to register.
     *  @param[in] context - User-defined context, which is often 'this' from
     *                       the interface implementation class.
     */
    interface(sdbusplus::bus::bus& bus, const char* path, const char* interf,
              const sdbusplus::vtable::vtable_t* vtable, void* context) :
        _bus(bus.get(), bus.getInterface()),
        _path(path), _interf(interf), _slot(nullptr), _intf(bus.getInterface()),
        _interface_added(false)
    {
        sd_bus_slot* slot = nullptr;
        _intf->sd_bus_add_object_vtable(_bus.get(), &slot, _path.c_str(),
                                        _interf.c_str(), vtable, context);

        _slot = decltype(_slot){slot};
    }

    ~interface()
    {
        emit_removed();
    }

    /** @brief Create a new signal message.
     *
     *  @param[in] member - The signal name to create.
     */
    auto new_signal(const char* member)
    {
        return _bus.new_signal(_path.c_str(), _interf.c_str(), member);
    }

    /** @brief Broadcast a property changed signal.
     *
     *  @param[in] property - The property which changed.
     */
    void property_changed(const char* property)
    {
        std::vector<std::string> values{property};
        sdbusplus::bus::details::Strv p(values);

        // Note: Converting to use _strv version, could also mock two pointer
        // use-case explicitly.
        _intf->sd_bus_emit_properties_changed_strv(
            _bus.get(), _path.c_str(), _interf.c_str(), static_cast<char**>(p));
    }

    /** @brief Emit the interface is added on D-Bus */
    void emit_added()
    {
        if (!_interface_added)
        {
            _bus.emit_interfaces_added(_path.c_str(), {_interf});
            _interface_added = true;
        }
    }

    /** @brief Emit the interface is removed on D-Bus */
    void emit_removed()
    {
        if (_interface_added)
        {
            _bus.emit_interfaces_removed(_path.c_str(), {_interf});
            _interface_added = false;
        }
    }

    bus::bus& bus()
    {
        return _bus;
    }
    const std::string& path()
    {
        return _path;
    }

  private:
    bus::bus _bus;
    std::string _path;
    std::string _interf;
    slot::slot _slot;
    SdBusInterface* _intf;
    bool _interface_added;
};

} // namespace interface

using interface_t = interface::interface;

} // namespace server
} // namespace sdbusplus
<commit_msg>server: Check return code for sd_bus_add_object_vtable()<commit_after>#pragma once

#include <systemd/sd-bus.h>

#include <sdbusplus/bus.hpp>
#include <sdbusplus/sdbus.hpp>
#include <sdbusplus/slot.hpp>
#include <sdbusplus/vtable.hpp>

#include <string>

namespace sdbusplus
{

namespace server
{

namespace interface
{

/** @class interface
 *  @brief Provide a C++ holder for dbus interface instances.
 *
 *  Wraps sd_bus_add_object_vtable so that the interface is registered
 *  on construction and deregistered on destruction.
 *
 *  @note This class is 'final' because it is expected to be used by an
 *  implementation of a class representing a dbus interface, which will be
 *  composed through multiple-inheritence to create a single dbus 'object'.
 *  Marking it 'final' prevents users from using an 'is-a' relationship via
 *  inheritance, which might be a natural option.  Instead, a dbus interface
 *  implementation should 'has-a' server::interface with a name sufficiently
 *  unique to prevent name collisions in multiple-inheritence situations.
 */
struct interface final
{
    /* Define all of the basic class operations:
     *     Not allowed:
     *         - Default constructor to avoid nullptrs.
     *         - Copy operations due to internal unique_ptr.
     *         - Move operations.
     *     Allowed:
     *         - Destructor.
     */
    interface() = delete;
    interface(const interface&) = delete;
    interface& operator=(const interface&) = delete;
    interface(interface&&) = delete;
    interface& operator=(interface&&) = delete;

    /** @brief Register the (path, interface, vtable) as a dbus object.
     *
     *  @param[in] bus - The bus to register on.
     *  @param[in] path - The path to register as.
     *  @param[in] interf - The interface to register as.
     *  @param[in] vtable - The vtable to register.
     *  @param[in] context - User-defined context, which is often 'this' from
     *                       the interface implementation class.
     */
    interface(sdbusplus::bus::bus& bus, const char* path, const char* interf,
              const sdbusplus::vtable::vtable_t* vtable, void* context) :
        _bus(bus.get(), bus.getInterface()),
        _path(path), _interf(interf), _slot(nullptr), _intf(bus.getInterface()),
        _interface_added(false)
    {
        sd_bus_slot* slot = nullptr;
        int r = _intf->sd_bus_add_object_vtable(
            _bus.get(), &slot, _path.c_str(), _interf.c_str(), vtable, context);
        if (r < 0)
        {
            throw exception::SdBusError(-r, "sd_bus_add_object_vtable");
        }

        _slot = decltype(_slot){slot};
    }

    ~interface()
    {
        emit_removed();
    }

    /** @brief Create a new signal message.
     *
     *  @param[in] member - The signal name to create.
     */
    auto new_signal(const char* member)
    {
        return _bus.new_signal(_path.c_str(), _interf.c_str(), member);
    }

    /** @brief Broadcast a property changed signal.
     *
     *  @param[in] property - The property which changed.
     */
    void property_changed(const char* property)
    {
        std::vector<std::string> values{property};
        sdbusplus::bus::details::Strv p(values);

        // Note: Converting to use _strv version, could also mock two pointer
        // use-case explicitly.
        _intf->sd_bus_emit_properties_changed_strv(
            _bus.get(), _path.c_str(), _interf.c_str(), static_cast<char**>(p));
    }

    /** @brief Emit the interface is added on D-Bus */
    void emit_added()
    {
        if (!_interface_added)
        {
            _bus.emit_interfaces_added(_path.c_str(), {_interf});
            _interface_added = true;
        }
    }

    /** @brief Emit the interface is removed on D-Bus */
    void emit_removed()
    {
        if (_interface_added)
        {
            _bus.emit_interfaces_removed(_path.c_str(), {_interf});
            _interface_added = false;
        }
    }

    bus::bus& bus()
    {
        return _bus;
    }
    const std::string& path()
    {
        return _path;
    }

  private:
    bus::bus _bus;
    std::string _path;
    std::string _interf;
    slot::slot _slot;
    SdBusInterface* _intf;
    bool _interface_added;
};

} // namespace interface

using interface_t = interface::interface;

} // namespace server
} // namespace sdbusplus
<|endoftext|>


<commit_before>#ifndef _SDD_HOM_SATURATION_FIXPOINT_HH_
#define _SDD_HOM_SATURATION_FIXPOINT_HH_

#include <algorithm>  // all_of, copy
#include <iosfwd>
#include <stdexcept>  //invalid_argument
#include <vector>

#include <boost/container/flat_set.hpp>

#include "sdd/dd/definition.hh"
#include "sdd/hom/context_fwd.hh"
#include "sdd/hom/definition_fwd.hh"
#include "sdd/hom/identity.hh"
#include "sdd/hom/local.hh"

namespace sdd { namespace hom {

/*-------------------------------------------------------------------------------------------*/

/// @cond INTERNAL_DOC

/// @brief Saturation Fixpoint homomorphism.
template <typename C>
class saturation_fixpoint
{
public:

  /// @brief The variable type.
  typedef typename C::Variable variable_type;

  /// @brief The type of the homomorphism G part.
  typedef boost::container::flat_set<homomorphism<C>> g_type;

private:

  /// @brief The variable on which this sum works.
  const variable_type variable_;

  /// @brief The homomorphism's F part.
  const homomorphism<C> F_;

  /// @brief The homomorphism's G part.
  const g_type G_;

  /// @brief The homomorphism's L part.
  const homomorphism<C> L_;

public:

  /// @brief Constructor.
  saturation_fixpoint( const variable_type& var, const homomorphism<C>& f, g_type&& g
                     , const homomorphism<C>& l)
    : variable_(var)
    , F_(f)
    , G_(std::move(g))
    , L_(l)
  {
  }

  /// @brief Evaluation.
  SDD<C>
  operator()(context<C>& cxt, const SDD<C>& s)
  const
  {
    SDD<C> s1 = s;
    SDD<C> s2 = s;

    do
    {
      s1 = s2;

      s2 = F_(cxt, s2); // apply (F + Id)*
      s2 = L_(cxt, s2); // apply (L + Id)*

      for (const auto& g : G_)
      {
//        sum_builder<C, SDD<C>> sum_operands(2);
//        sum_operands.add(s2);
//        sum_operands.add(g(cxt, s2));
        try
        {
          // chain applications of G
          s2 = sdd::sum(cxt.sdd_context(), {s2, g(cxt, s2)});
        }
        catch (top<C>& t)
        {
          evaluation_error<C> e(s);
          e.add_top(t);
          throw e;
        }
      }

    } while (s1 != s2);

    return s1;
  }

  /// @brief Skip variable predicate.
  bool
  skip(const typename C::Variable& v)
  const noexcept
  {
    return variable_ != v;
  }

  /// @brief Selector predicate.
  bool
  selector()
  const noexcept
  {
    return F_->selector()
       and L_->selector()
       and std::all_of( G_.begin(), G_.end()
                      , [](const homomorphism<C>& h){return h.selector();});
  }

  /// @brief Get the targeted variable.
  const variable_type&
  variable()
  const noexcept
  {
    return variable_;
  }

  /// @brief Get the forwardable part.
  homomorphism<C>
  F()
  const noexcept
  {
    return F_;
  }

  /// @brief Get the global part.
  const g_type&
  G()
  const noexcept
  {
    return G_;
  }

  /// @brief Get the local part.
  homomorphism<C>
  L()
  const noexcept
  {
    return L_;
  }
};

/*-------------------------------------------------------------------------------------------*/

/// @brief Equality of two saturation_fixpoint.
/// @related saturation_fixpoint
template <typename C>
inline
bool
operator==(const saturation_fixpoint<C>& lhs, const saturation_fixpoint<C>& rhs)
noexcept
{
  return lhs.variable() == rhs.variable()
     and lhs.F() == rhs.F()
     and lhs.L() == rhs.L()
     and lhs.G() == rhs.G();
}

/// @related sum
template <typename C>
std::ostream&
operator<<(std::ostream& os, const saturation_fixpoint<C>& s)
{
  os << "Sat(@" << s.variable() << ",  " << s.F() << " + " << s.L() << " + ";
  std::copy( s.G().begin(), std::prev(s.G().end())
           , std::ostream_iterator<homomorphism<C>>(os, " + "));
  return os << *std::prev(s.G().end()) << ")*";
}

/// @endcond

/*-------------------------------------------------------------------------------------------*/

/// @brief Create the Saturation Fixpoint homomorphism.
/// @related homomorphism
///
/// We suppose that a saturation fixpoint is created in the rewriting process. Thus, we assume
/// that operands of the G part are already optimized (e.g. local merged and sums flatten).
template <typename C, typename InputIterator>
homomorphism<C>
SaturationFixpoint( const typename C::Variable& var
                  , const homomorphism<C>& f
                  , InputIterator gbegin, InputIterator gend
                  , const homomorphism<C>& l)
{
  return homomorphism<C>::create( internal::mem::construct<saturation_fixpoint<C>>()
                                , var
                                , f
                                , typename saturation_fixpoint<C>::g_type(gbegin, gend)
                                , l);
}

/*-------------------------------------------------------------------------------------------*/

}} // namespace sdd::hom

namespace std {

/*-------------------------------------------------------------------------------------------*/

/// @cond INTERNAL_DOC

/// @brief Hash specialization for sdd::hom::saturation_fixpoint.
template <typename C>
struct hash<sdd::hom::saturation_fixpoint<C>>
{
  std::size_t
  operator()(const sdd::hom::saturation_fixpoint<C>& s)
  const noexcept
  {
    std::size_t seed = 0;
    sdd::internal::util::hash_combine(seed, s.variable());
    sdd::internal::util::hash_combine(seed, s.F());
    sdd::internal::util::hash_combine(seed, s.L());
    for (const auto& g : s.G())
    {
      sdd::internal::util::hash_combine(seed, g);
    }
    return seed;
  }
};

/// @endcond

/*-------------------------------------------------------------------------------------------*/

} // namespace std

#endif // _SDD_HOM_SATURATION_FIXPOINT_HH_
<commit_msg>Fix call to selector predicate.<commit_after>#ifndef _SDD_HOM_SATURATION_FIXPOINT_HH_
#define _SDD_HOM_SATURATION_FIXPOINT_HH_

#include <algorithm>  // all_of, copy
#include <iosfwd>
#include <stdexcept>  //invalid_argument
#include <vector>

#include <boost/container/flat_set.hpp>

#include "sdd/dd/definition.hh"
#include "sdd/hom/context_fwd.hh"
#include "sdd/hom/definition_fwd.hh"
#include "sdd/hom/identity.hh"
#include "sdd/hom/local.hh"

namespace sdd { namespace hom {

/*-------------------------------------------------------------------------------------------*/

/// @cond INTERNAL_DOC

/// @brief Saturation Fixpoint homomorphism.
template <typename C>
class saturation_fixpoint
{
public:

  /// @brief The variable type.
  typedef typename C::Variable variable_type;

  /// @brief The type of the homomorphism G part.
  typedef boost::container::flat_set<homomorphism<C>> g_type;

private:

  /// @brief The variable on which this sum works.
  const variable_type variable_;

  /// @brief The homomorphism's F part.
  const homomorphism<C> F_;

  /// @brief The homomorphism's G part.
  const g_type G_;

  /// @brief The homomorphism's L part.
  const homomorphism<C> L_;

public:

  /// @brief Constructor.
  saturation_fixpoint( const variable_type& var, const homomorphism<C>& f, g_type&& g
                     , const homomorphism<C>& l)
    : variable_(var)
    , F_(f)
    , G_(std::move(g))
    , L_(l)
  {
  }

  /// @brief Evaluation.
  SDD<C>
  operator()(context<C>& cxt, const SDD<C>& s)
  const
  {
    SDD<C> s1 = s;
    SDD<C> s2 = s;

    do
    {
      s1 = s2;

      s2 = F_(cxt, s2); // apply (F + Id)*
      s2 = L_(cxt, s2); // apply (L + Id)*

      for (const auto& g : G_)
      {
//        sum_builder<C, SDD<C>> sum_operands(2);
//        sum_operands.add(s2);
//        sum_operands.add(g(cxt, s2));
        try
        {
          // chain applications of G
          s2 = sdd::sum(cxt.sdd_context(), {s2, g(cxt, s2)});
        }
        catch (top<C>& t)
        {
          evaluation_error<C> e(s);
          e.add_top(t);
          throw e;
        }
      }

    } while (s1 != s2);

    return s1;
  }

  /// @brief Skip variable predicate.
  bool
  skip(const typename C::Variable& v)
  const noexcept
  {
    return variable_ != v;
  }

  /// @brief Selector predicate.
  bool
  selector()
  const noexcept
  {
    return F_.selector()
       and L_.selector()
       and std::all_of( G_.begin(), G_.end()
                      , [](const homomorphism<C>& h){return h.selector();});
  }

  /// @brief Get the targeted variable.
  const variable_type&
  variable()
  const noexcept
  {
    return variable_;
  }

  /// @brief Get the forwardable part.
  homomorphism<C>
  F()
  const noexcept
  {
    return F_;
  }

  /// @brief Get the global part.
  const g_type&
  G()
  const noexcept
  {
    return G_;
  }

  /// @brief Get the local part.
  homomorphism<C>
  L()
  const noexcept
  {
    return L_;
  }
};

/*-------------------------------------------------------------------------------------------*/

/// @brief Equality of two saturation_fixpoint.
/// @related saturation_fixpoint
template <typename C>
inline
bool
operator==(const saturation_fixpoint<C>& lhs, const saturation_fixpoint<C>& rhs)
noexcept
{
  return lhs.variable() == rhs.variable()
     and lhs.F() == rhs.F()
     and lhs.L() == rhs.L()
     and lhs.G() == rhs.G();
}

/// @related sum
template <typename C>
std::ostream&
operator<<(std::ostream& os, const saturation_fixpoint<C>& s)
{
  os << "Sat(@" << s.variable() << ",  " << s.F() << " + " << s.L() << " + ";
  std::copy( s.G().begin(), std::prev(s.G().end())
           , std::ostream_iterator<homomorphism<C>>(os, " + "));
  return os << *std::prev(s.G().end()) << ")*";
}

/// @endcond

/*-------------------------------------------------------------------------------------------*/

/// @brief Create the Saturation Fixpoint homomorphism.
/// @related homomorphism
///
/// We suppose that a saturation fixpoint is created in the rewriting process. Thus, we assume
/// that operands of the G part are already optimized (e.g. local merged and sums flatten).
template <typename C, typename InputIterator>
homomorphism<C>
SaturationFixpoint( const typename C::Variable& var
                  , const homomorphism<C>& f
                  , InputIterator gbegin, InputIterator gend
                  , const homomorphism<C>& l)
{
  return homomorphism<C>::create( internal::mem::construct<saturation_fixpoint<C>>()
                                , var
                                , f
                                , typename saturation_fixpoint<C>::g_type(gbegin, gend)
                                , l);
}

/*-------------------------------------------------------------------------------------------*/

}} // namespace sdd::hom

namespace std {

/*-------------------------------------------------------------------------------------------*/

/// @cond INTERNAL_DOC

/// @brief Hash specialization for sdd::hom::saturation_fixpoint.
template <typename C>
struct hash<sdd::hom::saturation_fixpoint<C>>
{
  std::size_t
  operator()(const sdd::hom::saturation_fixpoint<C>& s)
  const noexcept
  {
    std::size_t seed = 0;
    sdd::internal::util::hash_combine(seed, s.variable());
    sdd::internal::util::hash_combine(seed, s.F());
    sdd::internal::util::hash_combine(seed, s.L());
    for (const auto& g : s.G())
    {
      sdd::internal::util::hash_combine(seed, g);
    }
    return seed;
  }
};

/// @endcond

/*-------------------------------------------------------------------------------------------*/

} // namespace std

#endif // _SDD_HOM_SATURATION_FIXPOINT_HH_
<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2014, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ----------------------------------------------------------------------
 */

#include <iostream>
#include <assert.h>
#include <string>
#include <vector>
#include <utility>

#include <nupic/math/Math.hpp>
#include <nupic/math/SparseMatrix.hpp>
#include <nupic/math/SparseMatrix01.hpp>
#include <nupic/utils/Random.hpp>

using namespace std;
using namespace nupic;

// populate choices with a random selection of nChoices elements from
// population. throws exception when nPopulation < nChoices
// templated functions must be defined in header
template <typename PopulationIter, typename ChoicesIter>
void sample(PopulationIter population, UInt32 nPopulation,
            ChoicesIter choices, UInt32 nChoices, Random &r)
{
  if (nChoices == 0)
  {
    return;
  }
  if (nChoices > nPopulation)
  {
    NTA_THROW << "population size must be greater than number of choices";
  }
  UInt32 nextChoice = 0;
  for (UInt32 i = 0; i < nPopulation; ++i)
  {
    if (r.getUInt32(nPopulation - i) < (nChoices - nextChoice))
    {
      *choices++ = population[i];
      ++nextChoice;
      if (nextChoice == nChoices)
      {
        break;
      }
    }
  }
}

// Estimate the confidence bounds. This assumes a binomial distribution and
// computes the +- for a 95% confidence bound on a probability prob computed
// from the given number of trials.
Real estimateBounds(Real prob, Int trials)
{
  const Real z = 1.96;  // 95% from normal distribution
  Real stddev = sqrt((prob * (1.0 - prob)) / (Real)trials);
  return z * stddev;
}

// Given a set of patterns, a new pattern x, and a match threshold theta,
// return the number of matching vectors
int numMatches(SparseMatrix01<UInt, Int> &patterns,
               vector<UInt> &x, UInt theta)
{
  // Create a dense version of x
  vector<UInt> denseX;
  denseX.resize(patterns.nCols(), 0);
  for (auto it = x.begin(); it != x.end(); ++it)
  {
    denseX[*it] = 1;
  }

  // Create empty overlaps vector
  vector<UInt> overlaps;
  overlaps.resize(patterns.nRows(), 0);

  patterns.rightVecProd(denseX.begin(), overlaps.begin());

  int numMatches = 0;
  for (int i = 0; i < overlaps.size(); i++)
  {
    if (overlaps[i] >= theta) numMatches++;
  }

  return numMatches;
}

// Create M different vectors, each with w random bits on, and add them to sm.
// Each vectors will have sm.ncols()
void createRandomVectors(Int M, Int w, SparseMatrix01<UInt, Int> &sm,
                         Random &r, int verbosity=0)
{
  vector<UInt> population;
  for (int i= 0; i < sm.nCols(); i++) population.push_back(i);

  vector<UInt> activeBits;
  activeBits.resize(w);

  if (verbosity > 0)
  {
    cout << "Creating " << M << " random vectors with " << w << " bits on.\n";
  }
  for (Int m=0; m < M; m++)
  {
    // Randomly sample from columns
    sample(population.begin(), sm.nCols(), activeBits.begin(), w, r);
    sm.addRow(activeBits.size(), activeBits.begin());

    if (verbosity > 1)
    {
      cout << m << ":";
      for (Int i = 0; i < w; i++)
      {
        cout << activeBits[i] << " ";
      }
      cout << endl;
    }
  }

}

// Do a single classification trial. Given values for n, w, and M create N
// random vectors plus a random trial vector. For each value of theta from 1 to
// w, return the number of vectors that match.
void classificationFalseMatchTrial(
    UInt n, UInt w, UInt M, vector<UInt> &matchesWithThetas, Random &r)
{
  UInt32 population[n];
  for (Int i=0; i < n; i++) population[i] = i;

  // Generate our set of random sparse vectors and store in our "classifier"
  SparseMatrix01<UInt, Int> classifier(n, 1);
  createRandomVectors(M, w, classifier, r);

  // Generate our single random vector
  vector<UInt> x;
  x.resize(w, 0);
  sample(population, n, x.begin(), w, r);

  // Generate number of matches for each value of theta
  for (UInt theta = 1; theta <= w; theta++)
  {
    matchesWithThetas[theta] = numMatches(classifier, x, theta);
    //cout << "theta= " << theta << ", num matches= "
    //          << matchesWithThetas[theta] << "\n";
  }

}

// Given values for n, w, M, compute the probability of a false match for
// each value of theta = [1,w]. This is done by performing nTrials separate
// simulations, and seeing how often there is at least one match.
void classificationFalseMatchProbability(
    UInt n, UInt w, UInt M, vector<Real> &probWithThetas, UInt nTrials,
    Random &r)
{
  probWithThetas.clear();
  probWithThetas.resize(w+1, 0.0);

  for (int trial = 0; trial < nTrials; trial++)
  {
    vector<UInt> matchesWithThetas;
    matchesWithThetas.resize(w+1, 0);
    classificationFalseMatchTrial(n, w, M, matchesWithThetas, r);
    if (trial % 10000 == 0)
    {
      cout << trial << " trials completed out of " << nTrials << "\n";
    }

    for (UInt theta = 1; theta <= w; theta++)
    {
      if (matchesWithThetas[theta] > 0)
      {
        probWithThetas[theta]++;
      }
    }
  }

  cout << "Classification: Probability of false match for n=" << n
            << ", M=" << M << ", w=" << w << "\n";
  for (UInt theta = 1; theta <= w; theta++)
  {
    probWithThetas[theta] = (Real) probWithThetas[theta] / (Real) nTrials;
    auto bounds = estimateBounds(probWithThetas[theta], nTrials);
    cout << "    Theta = " << theta << " prob=" << probWithThetas[theta]
         << " +/- " << bounds
         << endl;
  }
}

// Run the trials!  Currently need to hard code the specific trial you are
// about to run.
int main(int argc, char * argv[]) {

  Random r;
  vector<Real> probWithThetas;

  cout << "Simulations running. Please be patient. Think about\n"
       << "all the things you have to be grateful for.\n\n";

  classificationFalseMatchProbability(1024, 30, 100, probWithThetas, 100000, r);
}

<commit_msg>Adds option for specifying subsampling for stored vectors.<commit_after>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2014, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ----------------------------------------------------------------------
 */

#include <iostream>
#include <assert.h>
#include <string>
#include <vector>
#include <utility>

#include <nupic/math/Math.hpp>
#include <nupic/math/SparseMatrix.hpp>
#include <nupic/math/SparseMatrix01.hpp>
#include <nupic/utils/Random.hpp>

using namespace std;
using namespace nupic;

// populate choices with a random selection of nChoices elements from
// population. throws exception when nPopulation < nChoices
// templated functions must be defined in header
template <typename PopulationIter, typename ChoicesIter>
void sample(PopulationIter population, UInt32 nPopulation,
            ChoicesIter choices, UInt32 nChoices, Random &r)
{
  if (nChoices == 0)
  {
    return;
  }
  if (nChoices > nPopulation)
  {
    NTA_THROW << "population size must be greater than number of choices";
  }
  UInt32 nextChoice = 0;
  for (UInt32 i = 0; i < nPopulation; ++i)
  {
    if (r.getUInt32(nPopulation - i) < (nChoices - nextChoice))
    {
      *choices++ = population[i];
      ++nextChoice;
      if (nextChoice == nChoices)
      {
        break;
      }
    }
  }
}

// Estimate the confidence bounds. This assumes a binomial distribution and
// computes the +- for a 95% confidence bound on a probability prob computed
// from the given number of trials.
Real estimateBounds(Real prob, Int trials)
{
  const Real z = 1.96;  // 95% from normal distribution
  Real stddev = sqrt((prob * (1.0 - prob)) / (Real)trials);
  return z * stddev;
}

// Given a set of patterns, a new pattern x, and a match threshold theta,
// return the number of matching vectors
int numMatches(SparseMatrix01<UInt, Int> &patterns,
               vector<UInt> &x, UInt theta)
{
  // Create a dense version of x
  vector<UInt> denseX;
  denseX.resize(patterns.nCols(), 0);
  for (auto it = x.begin(); it != x.end(); ++it)
  {
    denseX[*it] = 1;
  }

  // Create empty overlaps vector
  vector<UInt> overlaps;
  overlaps.resize(patterns.nRows(), 0);

  patterns.rightVecProd(denseX.begin(), overlaps.begin());

  int numMatches = 0;
  for (int i = 0; i < overlaps.size(); i++)
  {
    if (overlaps[i] >= theta) numMatches++;
  }

  return numMatches;
}

// Create M different vectors, each with w random bits on, and add them to sm.
// Each vectors will have sm.ncols()
void createRandomVectors(Int M, Int w, SparseMatrix01<UInt, Int> &sm,
                         Random &r, int verbosity=0)
{
  vector<UInt> population;
  for (int i= 0; i < sm.nCols(); i++) population.push_back(i);

  vector<UInt> activeBits;
  activeBits.resize(w);

  if (verbosity > 0)
  {
    cout << "Creating " << M << " random vectors with " << w << " bits on.\n";
  }
  for (Int m=0; m < M; m++)
  {
    // Randomly sample from columns
    sample(population.begin(), sm.nCols(), activeBits.begin(), w, r);
    sm.addRow(activeBits.size(), activeBits.begin());

    if (verbosity > 1)
    {
      cout << m << ":";
      for (Int i = 0; i < w; i++)
      {
        cout << activeBits[i] << " ";
      }
      cout << endl;
    }
  }

}

// Do a single classification trial. Given values for n, w, and M create N
// random vectors plus a random trial vector. For each value of theta from 1 to
// w, return the number of vectors that match.
void classificationFalseMatchTrial(
    UInt n, UInt w, UInt w_p, UInt M, vector<UInt> &matchesWithThetas,
    Random &r)
{
  NTA_ASSERT(w_p <= w < n);

  UInt32 population[n];
  for (Int i=0; i < n; i++) population[i] = i;

  // Create a list of stored patterns to put in the classifier
  SparseMatrix01<UInt, Int> storedPatterns(n, 1);
  createRandomVectors(M, w, storedPatterns, r);

  // Add subsampled versions of the vectors to the classifier
  SparseMatrix01<UInt, Int> classifier(n, 1);
  vector<UInt> originalRow;
  vector<UInt> subsampledRow;
  for (UInt i=0; i < M; ++i)
  {
    originalRow.clear();
    originalRow.resize(w);
    storedPatterns.getRowSparse(i, originalRow.begin());

    subsampledRow.clear();
    subsampledRow.resize(w_p);
    sample(originalRow.begin(), w, subsampledRow.begin(), w_p, r);
    classifier.addRow(w_p, subsampledRow.begin());
  }

  // Generate our single random vector
  vector<UInt> x;
  x.resize(w, 0);
  sample(population, n, x.begin(), w, r);

  // Generate number of matches for each value of theta
  for (UInt theta = 1; theta <= w_p; theta++)
  {
    matchesWithThetas[theta] = numMatches(classifier, x, theta);
    //cout << "theta= " << theta << ", num matches= "
    //          << matchesWithThetas[theta] << "\n";
  }

}

// Given values for n, w, w_p, M, compute the probability of a false match for
// each value of theta = [1,w]. This is done by performing nTrials separate
// simulations, and seeing how often there is at least one match.
//
// @param n number of bits per vector
// @param w number of active bits per vector
// @param w_p number of bits to subsample and store for each of M vectors
// @param M number of vectors to generate and store in classifier
// @param probWithThetas probabilities of false match for each theta value
// @param nTrials number of trials to run to compute probability
// @param r a random number generator
void classificationFalseMatchProbability(
    UInt n, UInt w, UInt w_p, UInt M, vector<Real> &probWithThetas,
    UInt nTrials, Random &r)
{
  NTA_ASSERT(w_p <= w < n);

  probWithThetas.clear();
  probWithThetas.resize(w_p+1, 0.0);

  for (int trial = 0; trial < nTrials; trial++)
  {
    vector<UInt> matchesWithThetas;
    matchesWithThetas.resize(w_p+1, 0);
    classificationFalseMatchTrial(n, w, w_p, M, matchesWithThetas, r);
    if (trial % 10000 == 0)
    {
      cout << trial << " trials completed out of " << nTrials << "\n";
    }

    for (UInt theta = 1; theta <= w_p; theta++)
    {
      if (matchesWithThetas[theta] > 0)
      {
        probWithThetas[theta]++;
      }
    }
  }

  cout << "Classification: Probability of false match for n=" << n
       << ", M=" << M << ", w=" << w << ", w'=" << w_p << "\n";
  for (UInt theta = 1; theta <= w_p; theta++)
  {
    probWithThetas[theta] = (Real) probWithThetas[theta] / (Real) nTrials;
    auto bounds = estimateBounds(probWithThetas[theta], nTrials);
    cout << "    Theta = " << theta << " prob=" << probWithThetas[theta]
         << " +/- " << bounds
         << endl;
  }
}

// Run the trials!  Currently need to hard code the specific trial you are
// about to run.
int main(int argc, char * argv[]) {

  Random r;
  vector<Real> probWithThetas;

  cout << "Simulations running. Please be patient. Think about\n"
       << "all the things you have to be grateful for.\n\n";

  classificationFalseMatchProbability(1024, 30, 30, 100, probWithThetas, 30000, r);
  classificationFalseMatchProbability(1024, 30, 20, 100, probWithThetas, 30000, r);
}

<|endoftext|>


<commit_before><commit_msg>fixed: ComponentTranform: update components on matrix changes<commit_after><|endoftext|>


<commit_before>#ifdef WITH_GUROBI
#include <stdlib.h>
#include <vector>
#include <set>
#include <functional>

#include <opengm/operations/adder.hxx>
#include <opengm/operations/multiplier.hxx>
#include <opengm/operations/minimizer.hxx>
#include <opengm/operations/maximizer.hxx>

#include <opengm/unittests/blackboxtester.hxx>
#include <opengm/unittests/blackboxtests/blackboxtestgrid.hxx>
#include <opengm/unittests/blackboxtests/blackboxtestfull.hxx>
#include <opengm/unittests/blackboxtests/blackboxteststar.hxx>
#include <opengm/graphicalmodel/graphicalmodel.hxx>
#include <opengm/unittests/test.hxx>
#include <opengm/inference/bruteforce.hxx>

#include <opengm/inference/auxiliary/lp_solver/lp_solver_gurobi.hxx>
#include <opengm/inference/lp_gurobi.hxx>

#endif

#include <iostream>

int main(){
#ifdef WITH_GUROBI
   {
      typedef opengm::GraphicalModel<double, opengm::Adder > SumGmType;
      typedef opengm::BlackBoxTestGrid<SumGmType> SumGridTest;
      typedef opengm::BlackBoxTestFull<SumGmType> SumFullTest;
      typedef opengm::BlackBoxTestStar<SumGmType> SumStarTest;

      typedef opengm::GraphicalModel<double, opengm::Multiplier > ProdGmType;
      typedef opengm::BlackBoxTestGrid<ProdGmType> ProdGridTest;
      typedef opengm::BlackBoxTestFull<ProdGmType> ProdFullTest;
      typedef opengm::BlackBoxTestStar<ProdGmType> ProdStarTest;

      opengm::InferenceBlackBoxTester<SumGmType> sumTester;
      sumTester.addTest(new SumGridTest(4, 4, 2, false, true, SumGridTest::RANDOM, opengm::PASS, 5));
      sumTester.addTest(new SumGridTest(4, 4, 2, false, false,SumGridTest::RANDOM, opengm::PASS, 5));
      sumTester.addTest(new SumStarTest(6,    4, false, true, SumStarTest::RANDOM, opengm::PASS, 20));
      sumTester.addTest(new SumFullTest(5,    2, false, 3,    SumFullTest::RANDOM, opengm::PASS, 5));

      opengm::InferenceBlackBoxTester<SumGmType> sumTesterOpt;
      sumTesterOpt.addTest(new SumGridTest(4, 4, 2, false, true, SumGridTest::RANDOM, opengm::OPTIMAL, 5));
      sumTesterOpt.addTest(new SumGridTest(4, 4, 2, false, false,SumGridTest::RANDOM, opengm::OPTIMAL, 5));
      sumTesterOpt.addTest(new SumStarTest(6,    4, false, true, SumStarTest::RANDOM, opengm::OPTIMAL, 20));
      sumTesterOpt.addTest(new SumFullTest(5,    2, false, 3,    SumFullTest::RANDOM, opengm::OPTIMAL, 5));

      opengm::InferenceBlackBoxTester<ProdGmType> prodTester;
      prodTester.addTest(new ProdGridTest(4, 4, 2, true, true, ProdGridTest::RANDOM, opengm::PASS, 5));

      opengm::InferenceBlackBoxTester<ProdGmType> prodTesterOpt;
      prodTesterOpt.addTest(new ProdGridTest(4, 4, 2, true, true, ProdGridTest::RANDOM, opengm::OPTIMAL, 5));

      std::cout << "Gurobi Tests"<<std::endl;
      {
         std::cout << "  * Minimization/Adder LP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Adder > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Minimizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.relaxation_        = Gurobi::FirstOrder;
         para.integerConstraint_ = false;
         sumTester.test<Gurobi>(para);
         para.relaxation_        = Gurobi::FirstOrder2;
         para.integerConstraint_ = false;
         sumTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Minimization/Adder ILP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Adder > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Minimizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.relaxation_        = Gurobi::FirstOrder;
         para.integerConstraint_ = true;
         sumTesterOpt.test<Gurobi>(para);
         para.relaxation_        = Gurobi::FirstOrder2;
         para.integerConstraint_ = true;
         sumTesterOpt.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Maximization/Adder LP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Adder > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Maximizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = false;
         sumTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Maximization/Adder ILP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Adder > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Maximizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = true;
         sumTesterOpt.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }

      {
         std::cout << "  * Minimization/Multiplier LP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Multiplier > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Minimizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = false;
         prodTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Minimization/Multiplier ILP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Multiplier > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Minimizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = true;
         prodTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }

      {
         std::cout << "  * Maximization/Multiplier LP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Multiplier > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Maximizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = false;
         prodTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Maximization/Multiplier ILP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Multiplier > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Maximizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = true;
         prodTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      std::cout << "done!"<<std::endl;
   }
#else
   std::cout << "LpGurobiTest test is disabled (compiled without LpCplex) "<< std::endl;
#endif
   return 0;
}

<commit_msg>improved lp gurobi interface<commit_after>#ifdef WITH_GUROBI
#include <stdlib.h>
#include <vector>
#include <set>
#include <functional>

#include <opengm/operations/adder.hxx>
#include <opengm/operations/multiplier.hxx>
#include <opengm/operations/minimizer.hxx>
#include <opengm/operations/maximizer.hxx>

#include <opengm/unittests/blackboxtester.hxx>
#include <opengm/unittests/blackboxtests/blackboxtestgrid.hxx>
#include <opengm/unittests/blackboxtests/blackboxtestfull.hxx>
#include <opengm/unittests/blackboxtests/blackboxteststar.hxx>
#include <opengm/graphicalmodel/graphicalmodel.hxx>
#include <opengm/unittests/test.hxx>
#include <opengm/inference/bruteforce.hxx>

#include <opengm/inference/auxiliary/lp_solver/lp_solver_gurobi.hxx>
#include <opengm/inference/lp_gurobi.hxx>

#endif

#include <iostream>

int main(){
#ifdef WITH_GUROBI
   {
      typedef opengm::GraphicalModel<double, opengm::Adder > SumGmType;
      typedef opengm::BlackBoxTestGrid<SumGmType> SumGridTest;
      typedef opengm::BlackBoxTestFull<SumGmType> SumFullTest;
      typedef opengm::BlackBoxTestStar<SumGmType> SumStarTest;

      typedef opengm::GraphicalModel<double, opengm::Multiplier > ProdGmType;
      typedef opengm::BlackBoxTestGrid<ProdGmType> ProdGridTest;
      typedef opengm::BlackBoxTestFull<ProdGmType> ProdFullTest;
      typedef opengm::BlackBoxTestStar<ProdGmType> ProdStarTest;

      opengm::InferenceBlackBoxTester<SumGmType> sumTester;
      sumTester.addTest(new SumGridTest(4, 4, 2, false, true, SumGridTest::RANDOM, opengm::PASS, 5));
      sumTester.addTest(new SumGridTest(4, 4, 2, false, false,SumGridTest::RANDOM, opengm::PASS, 5));
      sumTester.addTest(new SumStarTest(6,    4, false, true, SumStarTest::RANDOM, opengm::PASS, 20));
      sumTester.addTest(new SumFullTest(5,    2, false, 3,    SumFullTest::RANDOM, opengm::PASS, 5));

      opengm::InferenceBlackBoxTester<SumGmType> sumTesterOpt;
      sumTesterOpt.addTest(new SumGridTest(4, 4, 2, false, true, SumGridTest::RANDOM, opengm::OPTIMAL, 5));
      sumTesterOpt.addTest(new SumGridTest(4, 4, 2, false, false,SumGridTest::RANDOM, opengm::OPTIMAL, 5));
      sumTesterOpt.addTest(new SumStarTest(6,    4, false, true, SumStarTest::RANDOM, opengm::OPTIMAL, 20));
      sumTesterOpt.addTest(new SumFullTest(5,    2, false, 3,    SumFullTest::RANDOM, opengm::OPTIMAL, 5));

      opengm::InferenceBlackBoxTester<ProdGmType> prodTester;
      prodTester.addTest(new ProdGridTest(4, 4, 2, true, true, ProdGridTest::RANDOM, opengm::PASS, 5));

      opengm::InferenceBlackBoxTester<ProdGmType> prodTesterOpt;
      prodTesterOpt.addTest(new ProdGridTest(4, 4, 2, true, true, ProdGridTest::RANDOM, opengm::OPTIMAL, 5));

      std::cout << "Gurobi Tests"<<std::endl;
      {
         std::cout << "  * Minimization/Adder LP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Adder > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Minimizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.relaxation_        = Gurobi::FirstOrder;
         para.integerConstraint_ = false;
         sumTester.test<Gurobi>(para);
         para.relaxation_        = Gurobi::FirstOrder2;
         para.integerConstraint_ = false;
         sumTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Minimization/Adder ILP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Adder > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Minimizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.relaxation_        = Gurobi::FirstOrder;
         para.integerConstraint_ = true;
         sumTesterOpt.test<Gurobi>(para);
         para.relaxation_        = Gurobi::FirstOrder2;
         para.integerConstraint_ = true;
         para.integerConstraintFactorVar_ = true;
         sumTesterOpt.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Maximization/Adder LP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Adder > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Maximizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = false;
         sumTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Maximization/Adder ILP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Adder > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Maximizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = true;
         sumTesterOpt.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }

      {
         std::cout << "  * Minimization/Multiplier LP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Multiplier > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Minimizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = false;
         prodTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Minimization/Multiplier ILP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Multiplier > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Minimizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = true;
         prodTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }

      {
         std::cout << "  * Maximization/Multiplier LP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Multiplier > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Maximizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = false;
         prodTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      {
         std::cout << "  * Maximization/Multiplier ILP ..."<<std::endl;
         typedef opengm::GraphicalModel<double,opengm::Multiplier > GmType;
         typedef opengm::LpSolverGurobi LpSolver;
         typedef opengm::LPGurobi<GmType, opengm::Maximizer,LpSolver>    Gurobi;
         Gurobi::Parameter para;
         para.integerConstraint_ = true;
         prodTester.test<Gurobi>(para);
         std::cout << " OK!"<<std::endl;
      }
      std::cout << "done!"<<std::endl;
   }
#else
   std::cout << "LpGurobiTest test is disabled (compiled without LpCplex) "<< std::endl;
#endif
   return 0;
}

<|endoftext|>


<commit_before>#include <sys/stat.h>
#include <unistd.h>
#include"MdtmMan.h"
#include"zmq.h"
#include <fcntl.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

MdtmMan::MdtmMan(string local_address,
        string remote_address,
        string mode,
        string prefix,
        int num_pipes,
        vector<int> tolerance,
        vector<int> priority)
    :StreamMan(local_address, remote_address)
{
    pipe_desc["operation"] = "init";
    pipe_desc["mode"] = mode;
    pipe_desc["pipe_prefix"] = prefix;

    string pipename_prefix = "MdtmManPipe";
    for(int i=0; i<num_pipes; i++){
        stringstream pipename;
        pipename << pipename_prefix << i;
        if(i==0){
            pipe_desc["pipe_names"] = {pipename.str()};
            pipe_desc["loss_tolerance"] = {tolerance[i]};
            pipe_desc["priority"] = {priority[i]};
        }
        else{
            pipe_desc["pipe_names"].insert(pipe_desc["pipe_names"].end(), pipename.str());
            pipe_desc["loss_tolerance"].insert(pipe_desc["loss_tolerance"].end(), tolerance[i]);
            pipe_desc["priority"].insert(pipe_desc["priority"].end(), priority[i]);
        }
    }

    // ZMQ_DataMan_MDTM

    if(mode=="sender"){
        zmq_ipc_req = zmq_socket (zmq_context, ZMQ_REQ);
        zmq_ipc_rep = zmq_socket (zmq_context, ZMQ_REP);
        zmq_connect (zmq_ipc_req, "ipc:///tmp/ADIOS_MDTM_pipe");
        zmq_bind (zmq_ipc_rep, "ipc:///tmp/MDTM_ADIOS_pipe");

        char buffer_return[10];
        zmq_send (zmq_ipc_req, pipe_desc.dump().c_str(), pipe_desc.dump().length(), 0);
        zmq_recv (zmq_ipc_req, buffer_return, 10, 0);

        zmq_ipc_rep_thread_active = true;
        zmq_ipc_rep_thread = new thread(&MdtmMan::zmq_ipc_rep_thread_func, this);
    }
    // Pipes
    for (int i=0; i<pipe_desc["pipe_names"].size(); i++){
        string filename = prefix + rmquote(pipe_desc["pipe_names"][i].dump());
        mkfifo(filename.c_str(), 0666);
    }

    for(int i=0; i<num_pipes; i++){
        stringstream pipename;
        pipename << pipename_prefix << i;
        string fullpipename = prefix + pipename.str();
        cout << fullpipename << endl;
        if (mode == "sender"){
            int fp = open(fullpipename.c_str(), O_WRONLY);
            pipes.push_back(fp);
        }
        if (mode == "receiver"){
            int fp = open(fullpipename.c_str(), O_RDONLY | O_NONBLOCK);
            pipes.push_back(fp);
        }
        printf("pipe pointer %d ------------------- \n", pipes[i]);
        pipenames.push_back(pipename.str());
    }

}

MdtmMan::~MdtmMan(){
    if(zmq_ipc_rep) zmq_close (zmq_ipc_rep);
    if(zmq_ipc_req) zmq_close (zmq_ipc_req);
    zmq_ipc_rep_thread_active = false;
    zmq_ipc_rep_thread->join();
    delete zmq_ipc_rep_thread;
}

int MdtmMan::put(const void *data,
        string doid,
        string var,
        string dtype,
        vector<uint64_t> putshape,
        vector<uint64_t> varshape,
        vector<uint64_t> offset,
        int tolerance,
        int priority)
{
    json msg;
    msg["operation"] = "put";
    msg["doid"] = doid;
    msg["var"] = var;
    msg["dtype"] = dtype;
    msg["putshape"] = putshape;
    msg["varshape"] = varshape;
    msg["offset"] = offset;

    int index = closest(priority, pipe_desc["priority"], true);
    msg["pipe"] = pipe_desc["pipe_names"][index];

    uint64_t putsize = std::accumulate(putshape.begin(), putshape.end(), dsize(dtype), std::multiplies<uint64_t>());
    msg["putsize"] = putsize;
    uint64_t varsize = std::accumulate(varshape.begin(), varshape.end(), dsize(dtype), std::multiplies<uint64_t>());
    msg["varsize"] = varsize;

    cout << msg << endl;

    char ret[10];
    zmq_send(zmq_tcp_req, msg.dump().c_str(), msg.dump().length(), 0);
    zmq_recv(zmq_tcp_req, ret, 10, 0);

    index=0;
    for(int i=0; i<pipenames.size(); i++){
        if(rmquote(msg["pipe"].dump()) == pipenames[i]){
            index=i;
        }
    }
    string pipename = rmquote(pipe_desc["pipe_prefix"].dump()) + rmquote(msg["pipe"].dump());

    write(pipes[index], data, putsize);

    return 0;
}

void MdtmMan::get(json j){

    // push new request
    jqueue.push(j);
    int putsize = j["putsize"].get<int>();
    void *buf = malloc(putsize);
    bqueue.push(buf);
    iqueue.push(0);

    for(int outloop=0; outloop<10; outloop++){
        // determine the pipe for the head request
        json msg = jqueue.front();
        int index=0;
        for(int i=0; i<pipenames.size(); i++){
            if(rmquote(msg["pipe"]) == pipenames[i]){
                index=i;
            }
        }

        // read the head request
        int s = iqueue.front();
        putsize = msg["putsize"].get<int>();
        while(s<putsize){
            int ret = read(pipes[index], ((char*)bqueue.front()) + s, putsize - s);
            if(ret > 0){
                s += ret;
            }
            else{
                //                usleep(100);
                break;
            }
        }

	if(s == putsize){

		if(msg["offset"].get<vector<uint64_t>>()[1] < last_dim2){
			if(get_callback){
				get_callback(cache,
						"aaa",
						"data",
						"",
						vector<uint64_t>(),
						cache_shape,
						vector<uint64_t>());
			}
			uint64_t varsize = accumulate(cache_shape.begin(), cache_shape.end(), 1, multiplies<uint64_t>());
			for(int i=0; i<varsize; i++){
				((float*)cache)[i]=numeric_limits<float>::quiet_NaN();
			}
		}

		last_dim2 = msg["offset"].get<vector<uint64_t>>()[1];

		cache_it(bqueue.front(),
				msg["varshape"].get<vector<uint64_t>>(),
				msg["putshape"].get<vector<uint64_t>>(),
				msg["offset"].get<vector<uint64_t>>());
		free(bqueue.front());
		bqueue.pop();
		iqueue.pop();
		jqueue.pop();
	}
	else{
		iqueue.front()=s;
	}

    }

}

int MdtmMan::get(void *data, json j){
	return 0;
}

void MdtmMan::zmq_ipc_rep_thread_func(){
	while (zmq_ipc_rep_thread_active){
		char msg[1024];
		zmq_recv (zmq_ipc_rep, msg, 1024, ZMQ_NOBLOCK);
		zmq_send (zmq_ipc_rep, "OK", 10, 0);
		usleep(10000);
	}
}

<commit_msg>now works perfectly with MDTM, time to deploy on Singapore testbeds<commit_after>#include <sys/stat.h>
#include <unistd.h>
#include"MdtmMan.h"
#include"zmq.h"
#include <fcntl.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

MdtmMan::MdtmMan(string local_address,
        string remote_address,
        string mode,
        string prefix,
        int num_pipes,
        vector<int> tolerance,
        vector<int> priority)
    :StreamMan(local_address, remote_address)
{
    pipe_desc["operation"] = "init";
    pipe_desc["mode"] = mode;
    pipe_desc["pipe_prefix"] = prefix;

    string pipename_prefix = "MdtmManPipe";
    for(int i=0; i<num_pipes; i++){
        stringstream pipename;
        pipename << pipename_prefix << i;
        if(i==0){
            pipe_desc["pipe_names"] = {pipename.str()};
            pipe_desc["loss_tolerance"] = {tolerance[i]};
            pipe_desc["priority"] = {priority[i]};
        }
        else{
            pipe_desc["pipe_names"].insert(pipe_desc["pipe_names"].end(), pipename.str());
            pipe_desc["loss_tolerance"].insert(pipe_desc["loss_tolerance"].end(), tolerance[i]);
            pipe_desc["priority"].insert(pipe_desc["priority"].end(), priority[i]);
        }
    }

    // ZMQ_DataMan_MDTM

    if(mode=="sender"){
        zmq_ipc_req = zmq_socket (zmq_context, ZMQ_REQ);
        zmq_ipc_rep = zmq_socket (zmq_context, ZMQ_REP);
        zmq_connect (zmq_ipc_req, "ipc:///tmp/ADIOS_MDTM_pipe");
        zmq_bind (zmq_ipc_rep, "ipc:///tmp/MDTM_ADIOS_pipe");

        char buffer_return[10];
        zmq_send (zmq_ipc_req, pipe_desc.dump().c_str(), pipe_desc.dump().length(), 0);
        zmq_recv (zmq_ipc_req, buffer_return, 10, 0);

        zmq_ipc_rep_thread_active = true;
        zmq_ipc_rep_thread = new thread(&MdtmMan::zmq_ipc_rep_thread_func, this);
    }
    // Pipes
    for (int i=0; i<pipe_desc["pipe_names"].size(); i++){
        string filename = prefix + rmquote(pipe_desc["pipe_names"][i].dump());
        mkfifo(filename.c_str(), 0666);
    }

    for(int i=0; i<num_pipes; i++){
        stringstream pipename;
        pipename << pipename_prefix << i;
        string fullpipename = prefix + pipename.str();
        cout << fullpipename << endl;
        if (mode == "sender"){
            int fp = open(fullpipename.c_str(), O_WRONLY);
            pipes.push_back(fp);
        }
        if (mode == "receiver"){
            int fp = open(fullpipename.c_str(), O_RDONLY | O_NONBLOCK);
            pipes.push_back(fp);
        }
        printf("pipe pointer %d ------------------- \n", pipes[i]);
        pipenames.push_back(pipename.str());
    }

}

MdtmMan::~MdtmMan(){
    if(zmq_ipc_rep) zmq_close (zmq_ipc_rep);
    if(zmq_ipc_req) zmq_close (zmq_ipc_req);
    zmq_ipc_rep_thread_active = false;
    zmq_ipc_rep_thread->join();
    delete zmq_ipc_rep_thread;
}

int MdtmMan::put(const void *data,
        string doid,
        string var,
        string dtype,
        vector<uint64_t> putshape,
        vector<uint64_t> varshape,
        vector<uint64_t> offset,
        int tolerance,
        int priority)
{
    json msg;
    msg["operation"] = "put";
    msg["doid"] = doid;
    msg["var"] = var;
    msg["dtype"] = dtype;
    msg["putshape"] = putshape;
    msg["varshape"] = varshape;
    msg["offset"] = offset;

    int index = closest(priority, pipe_desc["priority"], true);
    msg["pipe"] = pipe_desc["pipe_names"][index];

    uint64_t putsize = std::accumulate(putshape.begin(), putshape.end(), dsize(dtype), std::multiplies<uint64_t>());
    msg["putsize"] = putsize;
    uint64_t varsize = std::accumulate(varshape.begin(), varshape.end(), dsize(dtype), std::multiplies<uint64_t>());
    msg["varsize"] = varsize;

    cout << msg << endl;

    char ret[10];
    zmq_send(zmq_tcp_req, msg.dump().c_str(), msg.dump().length(), 0);
    zmq_recv(zmq_tcp_req, ret, 10, 0);

    index=0;
    for(int i=0; i<pipenames.size(); i++){
        if(rmquote(msg["pipe"].dump()) == pipenames[i]){
            index=i;
        }
    }
    string pipename = rmquote(pipe_desc["pipe_prefix"].dump()) + rmquote(msg["pipe"].dump());

    write(pipes[index], data, putsize);

    return 0;
}

void MdtmMan::get(json j){

    // push new request
    jqueue.push(j);
    int putsize = j["putsize"].get<int>();
    void *buf = malloc(putsize);
    bqueue.push(buf);
    iqueue.push(0);

    for(int outloop=0; outloop<10; outloop++){
        // determine the pipe for the head request
        json msg = jqueue.front();
        int index=0;
        for(int i=0; i<pipenames.size(); i++){
            if(rmquote(msg["pipe"]) == pipenames[i]){
                index=i;
            }
        }

        // read the head request
        int s = iqueue.front();
        putsize = msg["putsize"].get<int>();
        while(s<putsize){
            int ret = read(pipes[index], ((char*)bqueue.front()) + s, putsize - s);
            if(ret > 0){
                s += ret;
            }
            else{
                //                usleep(100);
                break;
            }
        }

        if(s == putsize){

            if(msg["offset"].get<vector<uint64_t>>()[1] < last_dim2){
                if(get_callback){
                    get_callback(cache,
                            "aaa",
                            "data",
                            "",
                            vector<uint64_t>(),
                            cache_shape,
                            vector<uint64_t>());
                }
                uint64_t varsize = accumulate(cache_shape.begin(), cache_shape.end(), 1, multiplies<uint64_t>());
                for(int i=0; i<varsize; i++){
                    ((float*)cache)[i]=numeric_limits<float>::quiet_NaN();
                }
            }

            last_dim2 = msg["offset"].get<vector<uint64_t>>()[1];

            cache_it(bqueue.front(),
                    msg["varshape"].get<vector<uint64_t>>(),
                    msg["putshape"].get<vector<uint64_t>>(),
                    msg["offset"].get<vector<uint64_t>>());
            free(bqueue.front());
            bqueue.pop();
            iqueue.pop();
            jqueue.pop();
        }
        else{
            iqueue.front()=s;
        }

    }

}

int MdtmMan::get(void *data, json j){
    return 0;
}

void MdtmMan::zmq_ipc_rep_thread_func(){
    while (zmq_ipc_rep_thread_active){
        char msg[1024];
        zmq_recv (zmq_ipc_rep, msg, 1024, ZMQ_NOBLOCK);
        zmq_send (zmq_ipc_rep, "OK", 10, 0);
        usleep(10000);
    }
}

<|endoftext|>