<commit_before> /*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#include <rtl/ustring.hxx>
#include <osl/module.h>
#include <stdio.h>
#define  DECLARE_FN_POINTERS 1
#include "EApi.h"
static const char *eBookLibNames[] = {
    "libebook-1.2.so.9", // evolution-2.8
    "libebook-1.2.so.5", // evolution-2.4 and 2.6+
    "libebook-1.2.so.3", // evolution-2.2
    "libebook.so.8"      // evolution-2.0
};

typedef void (*SymbolFunc) (void);

#define SYM_MAP(a) { #a, (SymbolFunc *)&a }
    static struct {
    const char *sym_name;
    SymbolFunc *ref_value;
    } aApiMap[] = {
    SYM_MAP( e_contact_field_name ),
    SYM_MAP( e_contact_get ),
    SYM_MAP( e_contact_get_type ),
    SYM_MAP( e_contact_field_id ),
    SYM_MAP( e_source_peek_name ),
    SYM_MAP( e_source_get_property ),
    SYM_MAP( e_source_list_peek_groups ),
    SYM_MAP( e_source_group_peek_sources ),
    SYM_MAP( e_book_new ),
    SYM_MAP( e_book_open ),
    SYM_MAP( e_book_get_uri ),
    SYM_MAP( e_book_get_source ),
    SYM_MAP( e_book_get_addressbooks ),
    SYM_MAP( e_book_get_contacts ),
    SYM_MAP( e_book_authenticate_user ),
    SYM_MAP( e_book_query_field_test ),
    SYM_MAP( e_book_query_and ),
    SYM_MAP( e_book_query_or ),
    SYM_MAP( e_book_query_not ),
    SYM_MAP( e_book_query_ref ),
    SYM_MAP( e_book_query_unref ),
    SYM_MAP( e_book_query_from_string ),
    SYM_MAP( e_book_query_to_string ),
    SYM_MAP( e_book_query_field_exists ),
    SYM_MAP( e_source_group_peek_base_uri)
    };
#undef SYM_MAP

static bool
tryLink( oslModule &aModule, const char *pName )
{
    for( guint i = 0; i < G_N_ELEMENTS( aApiMap ); i++ )
    {
    SymbolFunc aMethod;
    aMethod = (SymbolFunc) osl_getFunctionSymbol
        ( aModule, rtl::OUString::createFromAscii ( aApiMap[ i ].sym_name ).pData );
    if( !aMethod )
    {
        fprintf( stderr, "Warning: missing symbol '%s' in '%s'",
             aApiMap[ i ].sym_name, pName );
        return false;
    }
    * aApiMap[ i ].ref_value = aMethod;
    }
    return true;
}

bool EApiInit()
{
    oslModule aModule;

    for( guint j = 0; j < G_N_ELEMENTS( eBookLibNames ); j++ )
    {
        aModule = osl_loadModule( rtl::OUString::createFromAscii
                                  ( eBookLibNames[ j ] ).pData,
                                  SAL_LOADMODULE_DEFAULT );
        if( aModule)
        {
            if ( tryLink( aModule, eBookLibNames[ j ] ) )
                return true;
            osl_unloadModule( aModule );
        }
    }
    fprintf( stderr, "Can find no compliant libebook client libraries\n" );
    return false;
}

#if 0
// hjs: SOLARDEF does no longer exist please lookup the required
// defines in a regular compile line
/*
 * Test code - enable &
 *
 * Compile with ( after source LinuxIntelEnv.Set.sh )
   gcc $SOLARDEF -I $SOLARVER/$UPD/$INPATH/inc \
     -I. `pkg-config --cflags --libs gobject-2.0` \
     -L $SOLARVER/$UPD/$INPATH/lib -luno_sal -lstdc++ EApi.cxx
 */

int main( int argc, char **argv)
{
    return EApiInit();
}

#endif

<commit_msg>libebook-1.2.so SONAME bumped again<commit_after> /*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

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

#include <rtl/ustring.hxx>
#include <osl/module.h>
#include <stdio.h>
#define  DECLARE_FN_POINTERS 1
#include "EApi.h"
static const char *eBookLibNames[] = {
    "libebook-1.2.so.10", // bumped again
    "libebook-1.2.so.9",  // evolution-2.8
    "libebook-1.2.so.5",  // evolution-2.4 and 2.6+
    "libebook-1.2.so.3",  // evolution-2.2
    "libebook.so.8"       // evolution-2.0
};

typedef void (*SymbolFunc) (void);

#define SYM_MAP(a) { #a, (SymbolFunc *)&a }
    static struct {
    const char *sym_name;
    SymbolFunc *ref_value;
    } aApiMap[] = {
    SYM_MAP( e_contact_field_name ),
    SYM_MAP( e_contact_get ),
    SYM_MAP( e_contact_get_type ),
    SYM_MAP( e_contact_field_id ),
    SYM_MAP( e_source_peek_name ),
    SYM_MAP( e_source_get_property ),
    SYM_MAP( e_source_list_peek_groups ),
    SYM_MAP( e_source_group_peek_sources ),
    SYM_MAP( e_book_new ),
    SYM_MAP( e_book_open ),
    SYM_MAP( e_book_get_uri ),
    SYM_MAP( e_book_get_source ),
    SYM_MAP( e_book_get_addressbooks ),
    SYM_MAP( e_book_get_contacts ),
    SYM_MAP( e_book_authenticate_user ),
    SYM_MAP( e_book_query_field_test ),
    SYM_MAP( e_book_query_and ),
    SYM_MAP( e_book_query_or ),
    SYM_MAP( e_book_query_not ),
    SYM_MAP( e_book_query_ref ),
    SYM_MAP( e_book_query_unref ),
    SYM_MAP( e_book_query_from_string ),
    SYM_MAP( e_book_query_to_string ),
    SYM_MAP( e_book_query_field_exists ),
    SYM_MAP( e_source_group_peek_base_uri)
    };
#undef SYM_MAP

static bool
tryLink( oslModule &aModule, const char *pName )
{
    for( guint i = 0; i < G_N_ELEMENTS( aApiMap ); i++ )
    {
    SymbolFunc aMethod;
    aMethod = (SymbolFunc) osl_getFunctionSymbol
        ( aModule, rtl::OUString::createFromAscii ( aApiMap[ i ].sym_name ).pData );
    if( !aMethod )
    {
        fprintf( stderr, "Warning: missing symbol '%s' in '%s'",
             aApiMap[ i ].sym_name, pName );
        return false;
    }
    * aApiMap[ i ].ref_value = aMethod;
    }
    return true;
}

bool EApiInit()
{
    oslModule aModule;

    for( guint j = 0; j < G_N_ELEMENTS( eBookLibNames ); j++ )
    {
        aModule = osl_loadModule( rtl::OUString::createFromAscii
                                  ( eBookLibNames[ j ] ).pData,
                                  SAL_LOADMODULE_DEFAULT );
        if( aModule)
        {
            if ( tryLink( aModule, eBookLibNames[ j ] ) )
                return true;
            osl_unloadModule( aModule );
        }
    }
    fprintf( stderr, "Can find no compliant libebook client libraries\n" );
    return false;
}

#if 0
// hjs: SOLARDEF does no longer exist please lookup the required
// defines in a regular compile line
/*
 * Test code - enable &
 *
 * Compile with ( after source LinuxIntelEnv.Set.sh )
   gcc $SOLARDEF -I $SOLARVER/$UPD/$INPATH/inc \
     -I. `pkg-config --cflags --libs gobject-2.0` \
     -L $SOLARVER/$UPD/$INPATH/lib -luno_sal -lstdc++ EApi.cxx
 */

int main( int argc, char **argv)
{
    return EApiInit();
}

#endif

<|endoftext|>


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

#ifndef CONNECTIVITY_TRESULTSETHELPER_HXX
#include "TResultSetHelper.hxx"
#endif

#ifndef _RTL_ALLOC_H_
#include <rtl/alloc.h>
#endif
#include <map>
#include <vector>

namespace connectivity
{
    /**
        the class OSkipDeletedSet supports a general method to skip deleted rows
    */
    class OSkipDeletedSet
    {
        typedef ::std::map<sal_Int32,sal_Int32> TInt2IntMap;
        TInt2IntMap                             m_aBookmarks;         // map from postion to logical position
        ::std::vector<TInt2IntMap::iterator>    m_aBookmarksPositions;// vector of iterators to position map, the order is the logical position
        IResultSetHelper*                       m_pHelper;            // used for moving in the resultset

        sal_Bool    moveAbsolute(sal_Int32 _nOffset,sal_Bool _bRetrieveData);
    public:
        OSkipDeletedSet(IResultSetHelper* _pHelper);
        ~OSkipDeletedSet();

        inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
            { return ::rtl_allocateMemory( nSize ); }
        inline static void * SAL_CALL operator new( size_t,void* _pHint ) SAL_THROW( () )
            { return _pHint; }
        inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
            { ::rtl_freeMemory( pMem ); }
        inline static void SAL_CALL operator delete( void *,void* ) SAL_THROW( () )
            {  }

        /**
            skipDeleted moves the resultset to the position defined by the parameters
            it garantees that the row isn't deleted
                @param
                    IResultSetHelper::Movement  _eCursorPosition        in which direction the resultset should be moved
                    sal_Int32                   _nOffset                the position relativ to the movement
                    sal_Bool                    _bRetrieveData          is true when the current row should be filled which data
                @return
                    true when the movement was successful otherwise false
        */
        sal_Bool    skipDeleted(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData);
        /**
            clear the map and the vector used in this class
        */
        void        clear();
        /**
            getMappedPosition returns the mapped position of a logical position
            @param
                sal_Int32 _nPos the logical position

            @return the mapped position
        */
        sal_Int32   getMappedPosition(sal_Int32 _nPos) const;
        /**
            insertNewPosition adds a new position to the map
            @param
                sal_Int32 _nPos the logical position
        */
        void        insertNewPosition(sal_Int32 _nPos);
        /**
            deletePosition deletes this position from the map and decrement all following positions
            @param
                sal_Int32 _nPos the logical position
        */
        void        deletePosition(sal_Int32 _nPos);
        /**
            getLastPosition returns the last position
            @return the last position
        */
        sal_Int32   getLastPosition() const { return m_aBookmarksPositions.size(); }
    };
}
#endif // CONNECTIVITY_SKIPDELETEDSSET_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.6.276); FILE MERGED 2008/04/01 15:09:07 thb 1.6.276.3: #i85898# Stripping all external header guards 2008/04/01 10:53:17 thb 1.6.276.2: #i85898# Stripping all external header guards 2008/03/28 15:24:05 rt 1.6.276.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: TSkipDeletedSet.hxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef CONNECTIVITY_SKIPDELETEDSSET_HXX
#define CONNECTIVITY_SKIPDELETEDSSET_HXX

#include "TResultSetHelper.hxx"
#include <rtl/alloc.h>
#include <map>
#include <vector>

namespace connectivity
{
    /**
        the class OSkipDeletedSet supports a general method to skip deleted rows
    */
    class OSkipDeletedSet
    {
        typedef ::std::map<sal_Int32,sal_Int32> TInt2IntMap;
        TInt2IntMap                             m_aBookmarks;         // map from postion to logical position
        ::std::vector<TInt2IntMap::iterator>    m_aBookmarksPositions;// vector of iterators to position map, the order is the logical position
        IResultSetHelper*                       m_pHelper;            // used for moving in the resultset

        sal_Bool    moveAbsolute(sal_Int32 _nOffset,sal_Bool _bRetrieveData);
    public:
        OSkipDeletedSet(IResultSetHelper* _pHelper);
        ~OSkipDeletedSet();

        inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
            { return ::rtl_allocateMemory( nSize ); }
        inline static void * SAL_CALL operator new( size_t,void* _pHint ) SAL_THROW( () )
            { return _pHint; }
        inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
            { ::rtl_freeMemory( pMem ); }
        inline static void SAL_CALL operator delete( void *,void* ) SAL_THROW( () )
            {  }

        /**
            skipDeleted moves the resultset to the position defined by the parameters
            it garantees that the row isn't deleted
                @param
                    IResultSetHelper::Movement  _eCursorPosition        in which direction the resultset should be moved
                    sal_Int32                   _nOffset                the position relativ to the movement
                    sal_Bool                    _bRetrieveData          is true when the current row should be filled which data
                @return
                    true when the movement was successful otherwise false
        */
        sal_Bool    skipDeleted(IResultSetHelper::Movement _eCursorPosition, sal_Int32 _nOffset, sal_Bool _bRetrieveData);
        /**
            clear the map and the vector used in this class
        */
        void        clear();
        /**
            getMappedPosition returns the mapped position of a logical position
            @param
                sal_Int32 _nPos the logical position

            @return the mapped position
        */
        sal_Int32   getMappedPosition(sal_Int32 _nPos) const;
        /**
            insertNewPosition adds a new position to the map
            @param
                sal_Int32 _nPos the logical position
        */
        void        insertNewPosition(sal_Int32 _nPos);
        /**
            deletePosition deletes this position from the map and decrement all following positions
            @param
                sal_Int32 _nPos the logical position
        */
        void        deletePosition(sal_Int32 _nPos);
        /**
            getLastPosition returns the last position
            @return the last position
        */
        sal_Int32   getLastPosition() const { return m_aBookmarksPositions.size(); }
    };
}
#endif // CONNECTIVITY_SKIPDELETEDSSET_HXX

<|endoftext|>


<commit_before>/*
    Copyright (C) 2012  Aleix Pol Gonzalez <aleixpol@blue-systems.com>

    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 Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "matchessolver.h"
#include "match.h"
#include "personsmodel.h"
#include <nepomuk2/datamanagement.h>
#include <QUrl>
#include <QDebug>

using namespace KPeople;

MatchesSolver::MatchesSolver(const QList<Match> &matches, PersonsModel *model, QObject *parent)
    : KJob(parent)
    , m_matches(matches)
    , m_model(model)
{
}

void MatchesSolver::start()
{
    QMetaObject::invokeMethod(this, "startMatching", Qt::QueuedConnection);
}

void MatchesSolver::startMatching()
{
    //group all matching pairs into a list of URIs indexed by the row of the 'destination' contact
    QMap<int, QSet<QUrl> > jobsData;
    Q_FOREACH(const Match &m, m_matches) {
        QPersistentModelIndex idxDestination = m.indexA;
        QPersistentModelIndex idxOrigin = m.indexB;
        Q_ASSERT(idxDestination.isValid() && idxOrigin.isValid());

        QSet<QUrl>& jobs = jobsData[idxDestination.row()];
        jobs.insert(idxDestination.data(PersonsModel::UriRole).toUrl());
        jobs.insert(idxOrigin.data(PersonsModel::UriRole).toUrl());
        Q_ASSERT(jobs.size()>=2);
    }

    Q_FOREACH(const QSet<QUrl>& uris, jobsData) {
        KJob* job = m_model->createPersonFromUris(uris.toList());
        //createPersonFromUris can return null if there nothing to be done
        if (job) {
            m_pending.insert(job);
            connect(job, SIGNAL(finished(KJob*)), SLOT(jobDone(KJob*)));
        } else {
            qWarning() << "error: failing to merge contacts: " << uris;
        }
    }

    //if there are no jobs in the queue emit finished
    if(m_pending.isEmpty()) {
        jobDone(0);
    }
}

void MatchesSolver::jobDone(KJob *job)
{
    m_pending.remove(job);
    if (m_pending.isEmpty()) {
        emitResult();
    }
}
<commit_msg>Fix the matchers resolver in MatchesSolver job<commit_after>/*
    Copyright (C) 2012  Aleix Pol Gonzalez <aleixpol@blue-systems.com>

    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 Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "matchessolver.h"
#include "match.h"
#include "personsmodel.h"
#include <nepomuk2/datamanagement.h>
#include <QUrl>
#include <QDebug>

using namespace KPeople;

MatchesSolver::MatchesSolver(const QList<Match> &matches, PersonsModel *model, QObject *parent)
    : KJob(parent)
    , m_matches(matches)
    , m_model(model)
{
}

void MatchesSolver::start()
{
    QMetaObject::invokeMethod(this, "startMatching", Qt::QueuedConnection);
}

void MatchesSolver::startMatching()
{
    //Will contain all the sets to be merged
    QHash<QUrl, QSet<QUrl> > jobsData;
    // has a relation of each person, to know where it is
    QHash<QUrl, QUrl> destinationResolver;
    Q_FOREACH(const Match &m, m_matches) {
        QUrl urlA = m.indexA.data(PersonsModel::UriRole).toUrl();
        QUrl urlB = m.indexB.data(PersonsModel::UriRole).toUrl();
        Q_ASSERT(urlA != urlB);

        const bool inA = destinationResolver.contains(urlA);
        const bool inB = destinationResolver.contains(urlB);
        if(inA && inB) {
            //Both are in already, so we have to merge both sets
            destinationResolver[urlB] = urlA;
            jobsData[urlA] = jobsData.take(urlB);

            //we've put all items pointed to by urlA, to the B set
            //now we re-assign anything pointing to B as pointing to A
            //because they are the same
            QList<QUrl> keys = destinationResolver.keys(urlB);
            foreach(const QUrl& key, keys) {
                destinationResolver[key] = urlA;
            }
        } else {
            //if A is in but not B, we want B wherever A is
            if(inA) {
                qSwap(urlB, urlA);
            }
            //in case B is anywhere, add A to that set, otherwise just insert B
            const QUrl mergeUrl = destinationResolver.value(urlB, urlB);

            QSet<QUrl>& jobs = jobsData[mergeUrl];
            jobs.insert(urlB);
            jobs.insert(urlA);

            //remember where urlA and urlB are
            Q_ASSERT(urlA != mergeUrl);
            destinationResolver.insert(urlA, mergeUrl);
            if (urlB != mergeUrl) {
                destinationResolver.insert(urlB, mergeUrl);
            }
        }
    }

    Q_FOREACH(const QSet<QUrl>& uris, jobsData) {
        KJob* job = m_model->createPersonFromUris(uris.toList());
        //createPersonFromUris can return null if there nothing to be done
        if (job) {
            m_pending.insert(job);
            connect(job, SIGNAL(finished(KJob*)), SLOT(jobDone(KJob*)));
        } else {
            qWarning() << "error: failing to merge contacts: " << uris;
        }
    }

    //if there are no jobs in the queue emit finished
    if(m_pending.isEmpty()) {
        jobDone(0);
    }
}

void MatchesSolver::jobDone(KJob *job)
{
    m_pending.remove(job);
    if (m_pending.isEmpty()) {
        emitResult();
    }
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "DataTradeCache.h"

#ifndef _MSC_VER
typedef CDataCache __super;
#endif

CDataTradeCache::CDataTradeCache(CFxQueue& queue)
    : CDataCache(queue)
    , m_isAccontInfoInitialized()
    , m_isOrdersInitialized()
{
}

CFxAccountInfo CDataTradeCache::GetAccountInfo()const
{
    CSharedLocker lock(m_synchronizer);
    return m_accountInfo;
}

vector<CFxOrder> CDataTradeCache::GetOrders() const
{
    vector<CFxOrder> result;
    CSharedLocker lock(m_synchronizer);
    foreach(const auto& entry, m_orders)
    {
        result.push_back(entry.second);
    }
    return result;
}

vector<CFxPositionReport> CDataTradeCache::GetPositions() const
{
    vector<CFxPositionReport> result;
    CSharedLocker lock(m_synchronizer);
    foreach(const auto& entry, m_positions)
    {
        result.push_back(entry.second);
    }
    return result;
}

void CDataTradeCache::Clear()
{
    DoClear();
    RaiseChanged();
    __super::Clear();
}

void CDataTradeCache::DoClear()
{
    CExclusiveLocker lock(m_synchronizer);
    m_accountInfo = CFxAccountInfo();
    m_isAccontInfoInitialized = false;
    m_isOrdersInitialized = false;
    m_reportsNumber = 0;
    m_orders.clear();
    m_positions.clear();
}

void CDataTradeCache::UpdateAccountInfo(const CFxAccountInfo& accountInfo)
{
    DoUpdateAccountInfo(accountInfo);
    RaiseChanged();
}

void CDataTradeCache::DoUpdateAccountInfo(const CFxAccountInfo& accountInfo)
{
    CExclusiveLocker lock(m_synchronizer);
    m_accountInfo = accountInfo;
    m_isAccontInfoInitialized = true;
    /* FDKPRO-511: DataTrade.Cache.TradeRecords.Length = 0 after EVENT Trade.CacheInitialized
    if (FxAccountType_Cash == m_accountInfo.Type || FxAccountType_Net ==  m_accountInfo.Type)
    {
        m_isOrdersInitialized = true;
    }
    */
    Update();
}

void CDataTradeCache::UpdateAssets(const string& currency, const double balance)
{
    DoUpdateAssets(currency, balance);
    RaiseChanged();
}

void CDataTradeCache::UpdateAssets(const vector<CAssetInfo>& assets)
{
    foreach(const auto& entry, assets)
    {
        DoUpdateAssets(entry.Currency, entry.Balance);
    }
    RaiseChanged();
}

void CDataTradeCache::DoUpdateAssets(const string& currency, const double balance)
{
    CExclusiveLocker lock(m_synchronizer);

    bool updated = false;

    for (size_t n = 0; n < m_accountInfo.Assets.size(); n++)
    {
        auto& entry = m_accountInfo.Assets[n];

        if (entry.Currency != currency)
            continue;

        entry.Balance = balance;
        updated = true;

        if (abs(entry.Balance) < DBL_EPSILON)
        {
            m_accountInfo.Assets.erase(m_accountInfo.Assets.begin() + n);
        }

        break;
    }

    if (!updated && (abs(balance) >= DBL_EPSILON))
    {
        CAssetInfo assetInfo;
        assetInfo.Currency = currency;
        assetInfo.Balance = balance;
        m_accountInfo.Assets.push_back(assetInfo);
    }

    Update();
}

void CDataTradeCache::UpdateOrders(const CFxExecutionReport& report)
{
    DoUpdateOrders(report);
    RaiseChanged();
}

void CDataTradeCache::DoUpdateOrders(const CFxExecutionReport& report)
{
    CExclusiveLocker lock(m_synchronizer);
    if (IsFinite(report.Balance))
    {
        m_accountInfo.Balance = report.Balance;
    }
    CFxOrder order;
    string orderId;
    double leavesVolume = 0;
    double commission = 0;
    double agentCommission = 0;
    double swap = 0;
    if (report.TryGetTradeRecord(order))
    {
        const string& id = order.OrderId;
        m_orders[id] = order;
    }
    else if (report.TryGetClosedPosition(orderId, leavesVolume, commission, agentCommission, swap))
    {
        auto it = m_orders.find(orderId);
        if (m_orders.end() != it)
        {
            if (leavesVolume > 0)
            {
                it->second.Volume = leavesVolume;
                it->second.Commission = commission;
                it->second.AgentCommission = agentCommission;
                it->second.Swap = swap;
            }
            else
            {
                m_orders.erase(it);
            }
        }
    }
    else if (report.TryGetDeletedOrder(orderId))
    {
        m_orders.erase(orderId);
    }
    else if (report.TryGetActivatedOrder(orderId))
    {
        m_orders.erase(orderId);
    }

    if (!m_isOrdersInitialized)
    {
        if (report.ReportsNumber == 0 || (int32)(++m_reportsNumber) == report.ReportsNumber)
        {
            m_isOrdersInitialized = true;
            Update();
        }
    }
}

void CDataTradeCache::Update()
{
    const bool isInitialized = m_isAccontInfoInitialized && m_isOrdersInitialized;
    __super::Update(isInitialized);
}

void CDataTradeCache::UpdateBalance(const double newBalance)
{
    DoUpdateBalance(newBalance);
    RaiseChanged();
}

void CDataTradeCache::DoUpdateBalance(const double newBalance)
{
    CExclusiveLocker lock(m_synchronizer);
    m_accountInfo.Balance = newBalance;
}

FxAccountType CDataTradeCache::GetAccountType() const
{
    CSharedLocker lock(m_synchronizer);
    return m_accountInfo.Type;
}

bool CDataTradeCache::GetSnapshot(FxAccountType& type, string& accountCurrency, int32& leverage, double& balance, map<string, CFxOrder>& orders, map<string, CFxPositionReport>& positions) const
{
    CSharedLocker lock(m_synchronizer);
    if (!m_isAccontInfoInitialized)
    {
        return false;
    }
    type = m_accountInfo.Type;
    accountCurrency = m_accountInfo.Currency;
    leverage = m_accountInfo.Leverage;
    balance = m_accountInfo.Balance;
    orders = m_orders;
    positions = m_positions;
    return true;
}

void CDataTradeCache::UpdatePosition(const CFxPositionReport& position)
{
    DoUpdatePosition(position);
    RaiseChanged();
}

void CDataTradeCache::DoUpdatePosition(const CFxPositionReport& position)
{
    CExclusiveLocker lock(m_synchronizer);
    m_positions[position.Symbol] = position;
    if (position.Balance.HasValue())
    {
        m_accountInfo.Balance = position.Balance.Value();
    }
}

void CDataTradeCache::RaiseChanged()
{
    Changed(*this);
}<commit_msg>FDKPRO-634: FDK1. If NET position is closed it still exists in _trader.Cache.Positions array<commit_after>#include "stdafx.h"
#include "DataTradeCache.h"

#ifndef _MSC_VER
typedef CDataCache __super;
#endif

CDataTradeCache::CDataTradeCache(CFxQueue& queue)
    : CDataCache(queue)
    , m_isAccontInfoInitialized()
    , m_isOrdersInitialized()
{
}

CFxAccountInfo CDataTradeCache::GetAccountInfo()const
{
    CSharedLocker lock(m_synchronizer);
    return m_accountInfo;
}

vector<CFxOrder> CDataTradeCache::GetOrders() const
{
    vector<CFxOrder> result;
    CSharedLocker lock(m_synchronizer);
    foreach(const auto& entry, m_orders)
    {
        result.push_back(entry.second);
    }
    return result;
}

vector<CFxPositionReport> CDataTradeCache::GetPositions() const
{
    vector<CFxPositionReport> result;
    CSharedLocker lock(m_synchronizer);
    foreach(const auto& entry, m_positions)
    {
        result.push_back(entry.second);
    }
    return result;
}

void CDataTradeCache::Clear()
{
    DoClear();
    RaiseChanged();
    __super::Clear();
}

void CDataTradeCache::DoClear()
{
    CExclusiveLocker lock(m_synchronizer);
    m_accountInfo = CFxAccountInfo();
    m_isAccontInfoInitialized = false;
    m_isOrdersInitialized = false;
    m_reportsNumber = 0;
    m_orders.clear();
    m_positions.clear();
}

void CDataTradeCache::UpdateAccountInfo(const CFxAccountInfo& accountInfo)
{
    DoUpdateAccountInfo(accountInfo);
    RaiseChanged();
}

void CDataTradeCache::DoUpdateAccountInfo(const CFxAccountInfo& accountInfo)
{
    CExclusiveLocker lock(m_synchronizer);
    m_accountInfo = accountInfo;
    m_isAccontInfoInitialized = true;
    /* FDKPRO-511: DataTrade.Cache.TradeRecords.Length = 0 after EVENT Trade.CacheInitialized
    if (FxAccountType_Cash == m_accountInfo.Type || FxAccountType_Net ==  m_accountInfo.Type)
    {
        m_isOrdersInitialized = true;
    }
    */
    Update();
}

void CDataTradeCache::UpdateAssets(const string& currency, const double balance)
{
    DoUpdateAssets(currency, balance);
    RaiseChanged();
}

void CDataTradeCache::UpdateAssets(const vector<CAssetInfo>& assets)
{
    foreach(const auto& entry, assets)
    {
        DoUpdateAssets(entry.Currency, entry.Balance);
    }
    RaiseChanged();
}

void CDataTradeCache::DoUpdateAssets(const string& currency, const double balance)
{
    CExclusiveLocker lock(m_synchronizer);

    bool updated = false;

    for (size_t n = 0; n < m_accountInfo.Assets.size(); n++)
    {
        auto& entry = m_accountInfo.Assets[n];

        if (entry.Currency != currency)
            continue;

        entry.Balance = balance;
        updated = true;

        if (abs(entry.Balance) < DBL_EPSILON)
        {
            m_accountInfo.Assets.erase(m_accountInfo.Assets.begin() + n);
        }

        break;
    }

    if (!updated && (abs(balance) >= DBL_EPSILON))
    {
        CAssetInfo assetInfo;
        assetInfo.Currency = currency;
        assetInfo.Balance = balance;
        m_accountInfo.Assets.push_back(assetInfo);
    }

    Update();
}

void CDataTradeCache::UpdateOrders(const CFxExecutionReport& report)
{
    DoUpdateOrders(report);
    RaiseChanged();
}

void CDataTradeCache::DoUpdateOrders(const CFxExecutionReport& report)
{
    CExclusiveLocker lock(m_synchronizer);
    if (IsFinite(report.Balance))
    {
        m_accountInfo.Balance = report.Balance;
    }
    CFxOrder order;
    string orderId;
    double leavesVolume = 0;
    double commission = 0;
    double agentCommission = 0;
    double swap = 0;
    if (report.TryGetTradeRecord(order))
    {
        const string& id = order.OrderId;
        m_orders[id] = order;
    }
    else if (report.TryGetClosedPosition(orderId, leavesVolume, commission, agentCommission, swap))
    {
        auto it = m_orders.find(orderId);
        if (m_orders.end() != it)
        {
            if (leavesVolume > 0)
            {
                it->second.Volume = leavesVolume;
                it->second.Commission = commission;
                it->second.AgentCommission = agentCommission;
                it->second.Swap = swap;
            }
            else
            {
                m_orders.erase(it);
            }
        }
    }
    else if (report.TryGetDeletedOrder(orderId))
    {
        m_orders.erase(orderId);
    }
    else if (report.TryGetActivatedOrder(orderId))
    {
        m_orders.erase(orderId);
    }

    if (!m_isOrdersInitialized)
    {
        if (report.ReportsNumber == 0 || (int32)(++m_reportsNumber) == report.ReportsNumber)
        {
            m_isOrdersInitialized = true;
            Update();
        }
    }
}

void CDataTradeCache::Update()
{
    const bool isInitialized = m_isAccontInfoInitialized && m_isOrdersInitialized;
    __super::Update(isInitialized);
}

void CDataTradeCache::UpdateBalance(const double newBalance)
{
    DoUpdateBalance(newBalance);
    RaiseChanged();
}

void CDataTradeCache::DoUpdateBalance(const double newBalance)
{
    CExclusiveLocker lock(m_synchronizer);
    m_accountInfo.Balance = newBalance;
}

FxAccountType CDataTradeCache::GetAccountType() const
{
    CSharedLocker lock(m_synchronizer);
    return m_accountInfo.Type;
}

bool CDataTradeCache::GetSnapshot(FxAccountType& type, string& accountCurrency, int32& leverage, double& balance, map<string, CFxOrder>& orders, map<string, CFxPositionReport>& positions) const
{
    CSharedLocker lock(m_synchronizer);
    if (!m_isAccontInfoInitialized)
    {
        return false;
    }
    type = m_accountInfo.Type;
    accountCurrency = m_accountInfo.Currency;
    leverage = m_accountInfo.Leverage;
    balance = m_accountInfo.Balance;
    orders = m_orders;
    positions = m_positions;
    return true;
}

void CDataTradeCache::UpdatePosition(const CFxPositionReport& position)
{
    DoUpdatePosition(position);
    RaiseChanged();
}

void CDataTradeCache::DoUpdatePosition(const CFxPositionReport& position)
{
    CExclusiveLocker lock(m_synchronizer);
    m_positions[position.Symbol] = position;
    if (position.Balance.HasValue())
    {
        m_accountInfo.Balance = position.Balance.Value();
    }

    if (position.BuyAmount == 0 && position.SellAmount == 0)
    {
        m_positions.erase(position.Symbol);
    }
}

void CDataTradeCache::RaiseChanged()
{
    Changed(*this);
}<|endoftext|>


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

#include "content/common/font_cache_dispatcher_win.h"

#include <vector>
#include <map>

#include "base/logging.h"
#include "base/string16.h"
#include "content/common/child_process_messages.h"

namespace {
typedef std::vector<string16> FontNameVector;
typedef std::map<FontCacheDispatcher*, FontNameVector> DispatcherToFontNames;

class FontCache {
 public:
  static FontCache* GetInstance() {
    return Singleton<FontCache>::get();
  }

  void PreCacheFont(const LOGFONT& font, FontCacheDispatcher* dispatcher) {
    typedef std::map<string16, FontCache::CacheElement> FontNameToElement;

    base::AutoLock lock(mutex_);

    // Fetch the font into memory.
    // No matter the font is cached or not, we load it to avoid GDI swapping out
    // that font file.
    HDC hdc = GetDC(NULL);
    HFONT font_handle = CreateFontIndirect(&font);
    DCHECK(NULL != font_handle);

    HGDIOBJ old_font = SelectObject(hdc, font_handle);
    DCHECK(NULL != old_font);

    TEXTMETRIC tm;
    BOOL ret = GetTextMetrics(hdc, &tm);
    DCHECK(ret);

    string16 font_name = font.lfFaceName;
    int ref_count_inc = 1;
    FontNameVector::iterator it =
        std::find(dispatcher_font_map_[dispatcher].begin(),
                  dispatcher_font_map_[dispatcher].end(),
                  font_name);
    if (it == dispatcher_font_map_[dispatcher].end()) {
      // Requested font is new to cache.
      dispatcher_font_map_[dispatcher].push_back(font_name);
    } else {
      ref_count_inc = 0;
    }

    if (cache_[font_name].ref_count_ == 0) {  // Requested font is new to cache.
      cache_[font_name].ref_count_ = 1;
    } else {  // Requested font is already in cache, release old handles.
      DeleteObject(cache_[font_name].font_);
      DeleteDC(cache_[font_name].dc_);
    }
    cache_[font_name].font_ = font_handle;
    cache_[font_name].dc_ = hdc;
    cache_[font_name].ref_count_ += ref_count_inc;
  }

  void ReleaseCachedFonts(FontCacheDispatcher* dispatcher) {
    typedef std::map<string16, FontCache::CacheElement> FontNameToElement;

    base::AutoLock lock(mutex_);

    DispatcherToFontNames::iterator it;
    it = dispatcher_font_map_.find(dispatcher);
    if (it == dispatcher_font_map_.end()) {
      return;
    }

    for (FontNameVector::iterator i = it->second.begin(), e = it->second.end();
                                  i != e; ++i) {
      FontNameToElement::iterator element;
      element = cache_.find(*i);
      if (element != cache_.end()) {
        --((*element).second.ref_count_);
      }
    }

    dispatcher_font_map_.erase(it);
    for (FontNameToElement::iterator i = cache_.begin(); i != cache_.end(); ) {
      if (i->second.ref_count_ == 0) {
        cache_.erase(i++);
      } else {
        ++i;
      }
    }
  }

 private:
  struct CacheElement {
    CacheElement()
        : font_(NULL), dc_(NULL), ref_count_(0) {
    }

    ~CacheElement() {
      if (font_) {
        DeleteObject(font_);
      }
      if (dc_) {
        DeleteDC(dc_);
      }
    }

    HFONT font_;
    HDC dc_;
    int ref_count_;
  };
  friend struct DefaultSingletonTraits<FontCache>;

  FontCache() {
  }

  std::map<string16, CacheElement> cache_;
  DispatcherToFontNames dispatcher_font_map_;
  base::Lock mutex_;

  DISALLOW_COPY_AND_ASSIGN(FontCache);
};

}

FontCacheDispatcher::FontCacheDispatcher()
    : channel_(NULL) {
}

FontCacheDispatcher::~FontCacheDispatcher() {
}

void FontCacheDispatcher::OnFilterAdded(IPC::Channel* channel) {
  channel_ = channel;
}

bool FontCacheDispatcher::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(FontCacheDispatcher, message)
    IPC_MESSAGE_HANDLER(ChildProcessHostMsg_PreCacheFont, OnPreCacheFont)
    IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ReleaseCachedFonts,
                        OnReleaseCachedFonts)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void FontCacheDispatcher::OnChannelClosing() {
  channel_ = NULL;
}

bool FontCacheDispatcher::Send(IPC::Message* message) {
  if (channel_)
    return channel_->Send(message);

  delete message;
  return false;
}

void FontCacheDispatcher::OnPreCacheFont(const LOGFONT& font) {
  // If a child process is running in a sandbox, GetTextMetrics()
  // can sometimes fail. If a font has not been loaded
  // previously, GetTextMetrics() will try to load the font
  // from the font file. However, the sandboxed process does
  // not have permissions to access any font files and
  // the call fails. So we make the browser pre-load the
  // font for us by using a dummy call to GetTextMetrics of
  // the same font.
  // This means the browser process just loads the font into memory so that
  // when GDI attempt to query that font info in child process, it does not
  // need to load that file, hence no permission issues there.  Therefore,
  // when a font is asked to be cached, we always recreates the font object
  // to avoid the case that an in-cache font is swapped out by GDI.
  FontCache::GetInstance()->PreCacheFont(font, this);
}

void FontCacheDispatcher::OnReleaseCachedFonts() {
  // Release cached fonts that requested from a pid by decrementing the ref
  // count.  When ref count is zero, the handles are released.
  FontCache::GetInstance()->ReleaseCachedFonts(this);
}
<commit_msg>fix GDI usage errors: + use ReleaseDC to free DC obtained via GetDC + de-select font object prior to deleting it<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/common/font_cache_dispatcher_win.h"

#include <vector>
#include <map>

#include "base/logging.h"
#include "base/string16.h"
#include "content/common/child_process_messages.h"

namespace {
typedef std::vector<string16> FontNameVector;
typedef std::map<FontCacheDispatcher*, FontNameVector> DispatcherToFontNames;

class FontCache {
 public:
  static FontCache* GetInstance() {
    return Singleton<FontCache>::get();
  }

  void PreCacheFont(const LOGFONT& font, FontCacheDispatcher* dispatcher) {
    typedef std::map<string16, FontCache::CacheElement> FontNameToElement;

    base::AutoLock lock(mutex_);

    // Fetch the font into memory.
    // No matter the font is cached or not, we load it to avoid GDI swapping out
    // that font file.
    HDC hdc = GetDC(NULL);
    HFONT font_handle = CreateFontIndirect(&font);
    DCHECK(NULL != font_handle);

    HGDIOBJ old_font = SelectObject(hdc, font_handle);
    DCHECK(NULL != old_font);

    TEXTMETRIC tm;
    BOOL ret = GetTextMetrics(hdc, &tm);
    DCHECK(ret);

    string16 font_name = font.lfFaceName;
    int ref_count_inc = 1;
    FontNameVector::iterator it =
        std::find(dispatcher_font_map_[dispatcher].begin(),
                  dispatcher_font_map_[dispatcher].end(),
                  font_name);
    if (it == dispatcher_font_map_[dispatcher].end()) {
      // Requested font is new to cache.
      dispatcher_font_map_[dispatcher].push_back(font_name);
    } else {
      ref_count_inc = 0;
    }

    if (cache_[font_name].ref_count_ == 0) {  // Requested font is new to cache.
      cache_[font_name].ref_count_ = 1;
    } else {  // Requested font is already in cache, release old handles.
      SelectObject(cache_[font_name].dc_, cache_[font_name].old_font_);
      DeleteObject(cache_[font_name].font_);
      ReleaseDC(NULL, cache_[font_name].dc_);
    }
    cache_[font_name].font_ = font_handle;
    cache_[font_name].dc_ = hdc;
    cache_[font_name].old_font_ = old_font;
    cache_[font_name].ref_count_ += ref_count_inc;
  }

  void ReleaseCachedFonts(FontCacheDispatcher* dispatcher) {
    typedef std::map<string16, FontCache::CacheElement> FontNameToElement;

    base::AutoLock lock(mutex_);

    DispatcherToFontNames::iterator it;
    it = dispatcher_font_map_.find(dispatcher);
    if (it == dispatcher_font_map_.end()) {
      return;
    }

    for (FontNameVector::iterator i = it->second.begin(), e = it->second.end();
                                  i != e; ++i) {
      FontNameToElement::iterator element;
      element = cache_.find(*i);
      if (element != cache_.end()) {
        --((*element).second.ref_count_);
      }
    }

    dispatcher_font_map_.erase(it);
    for (FontNameToElement::iterator i = cache_.begin(); i != cache_.end(); ) {
      if (i->second.ref_count_ == 0) {
        cache_.erase(i++);
      } else {
        ++i;
      }
    }
  }

 private:
  struct CacheElement {
    CacheElement()
        : font_(NULL), old_font_(NULL), dc_(NULL), ref_count_(0) {
    }

    ~CacheElement() {
      if (font_) {
        if (dc_ && old_font_) {
          SelectObject(dc_, old_font_);
        }
        DeleteObject(font_);
      }
      if (dc_) {
        ReleaseDC(NULL, dc_);
      }
    }

    HFONT font_;
    HGDIOBJ old_font_;
    HDC dc_;
    int ref_count_;
  };
  friend struct DefaultSingletonTraits<FontCache>;

  FontCache() {
  }

  std::map<string16, CacheElement> cache_;
  DispatcherToFontNames dispatcher_font_map_;
  base::Lock mutex_;

  DISALLOW_COPY_AND_ASSIGN(FontCache);
};

}

FontCacheDispatcher::FontCacheDispatcher()
    : channel_(NULL) {
}

FontCacheDispatcher::~FontCacheDispatcher() {
}

void FontCacheDispatcher::OnFilterAdded(IPC::Channel* channel) {
  channel_ = channel;
}

bool FontCacheDispatcher::OnMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(FontCacheDispatcher, message)
    IPC_MESSAGE_HANDLER(ChildProcessHostMsg_PreCacheFont, OnPreCacheFont)
    IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ReleaseCachedFonts,
                        OnReleaseCachedFonts)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void FontCacheDispatcher::OnChannelClosing() {
  channel_ = NULL;
}

bool FontCacheDispatcher::Send(IPC::Message* message) {
  if (channel_)
    return channel_->Send(message);

  delete message;
  return false;
}

void FontCacheDispatcher::OnPreCacheFont(const LOGFONT& font) {
  // If a child process is running in a sandbox, GetTextMetrics()
  // can sometimes fail. If a font has not been loaded
  // previously, GetTextMetrics() will try to load the font
  // from the font file. However, the sandboxed process does
  // not have permissions to access any font files and
  // the call fails. So we make the browser pre-load the
  // font for us by using a dummy call to GetTextMetrics of
  // the same font.
  // This means the browser process just loads the font into memory so that
  // when GDI attempt to query that font info in child process, it does not
  // need to load that file, hence no permission issues there.  Therefore,
  // when a font is asked to be cached, we always recreates the font object
  // to avoid the case that an in-cache font is swapped out by GDI.
  FontCache::GetInstance()->PreCacheFont(font, this);
}

void FontCacheDispatcher::OnReleaseCachedFonts() {
  // Release cached fonts that requested from a pid by decrementing the ref
  // count.  When ref count is zero, the handles are released.
  FontCache::GetInstance()->ReleaseCachedFonts(this);
}
<|endoftext|>


<commit_before>#include "solver_factory.h"

#include <iostream>

#include "OsiClpSolverInterface.hpp"
#include "OsiCbcSolverInterface.hpp"
#include "CbcSolver.hpp"
#include "CoinTime.hpp"

#include "error.h"

namespace cyclus {

int CbcCallBack(CbcModel * model, int from) {
  int ret = 0;
  switch (from) {
  case 1:
  case 2:
    if (!model->status() && model->secondaryStatus())
      ret=1;
    break;
  case 3:
  case 4:
  case 5:
    break;
  }
  return ret;
}

ObjValueHandler::ObjValueHandler(double obj, double time, bool found)
  : obj_(obj),
    time_(time),
    found_(found) { };

ObjValueHandler::ObjValueHandler(double obj)
  : obj_(obj),
    time_(0),
    found_(false) { };

ObjValueHandler::~ObjValueHandler() { };

ObjValueHandler::ObjValueHandler(const ObjValueHandler& other): CbcEventHandler(other) {
  obj_ = other.obj();
  time_ = other.time();
  found_ = other.found();
}

ObjValueHandler& ObjValueHandler::operator=(const ObjValueHandler& other) {
  if (this != &other) {
    obj_ = other.obj();
    time_ = other.time();
    found_ = other.found();
    CbcEventHandler::operator=(other);
  }
  return *this;
}

CbcEventHandler* ObjValueHandler::clone() {
  return new ObjValueHandler(*this);
}

CbcEventHandler::CbcAction ObjValueHandler::event(CbcEvent e) {
  if (!found_ && (e == solution || e == heuristicSolution)) {
    const CbcModel* m = getModel();
    double cbcobj = m->getObjValue();
    if (cbcobj < obj_) {
      time_ = CoinCpuTime() -
              m->getDblParam(CbcModel::CbcStartSeconds);
      found_ = true;
    }
  }
  return noAction;
}

// 10800 s = 3 hrs * 60 min/hr * 60 s/min
#define CYCLUS_SOLVER_TIMEOUT 10800

SolverFactory::SolverFactory() : t_("cbc"), tmax_(CYCLUS_SOLVER_TIMEOUT) { }
SolverFactory::SolverFactory(std::string t) : t_(t), tmax_(CYCLUS_SOLVER_TIMEOUT) { }
SolverFactory::SolverFactory(std::string t, double tmax)
    : t_(t),
      tmax_(tmax) { }

OsiSolverInterface* SolverFactory::get() {
  if (t_ == "clp" || t_ == "cbc") {
    OsiClpSolverInterface* s = new OsiClpSolverInterface();
    s->getModelPtr()->setMaximumSeconds(tmax_);
    return s;
  } else {
    throw ValueError("invalid SolverFactory type '" + t_ + "'");
  }
}

void ReportProg(OsiSolverInterface* si) {
  const double* objs = si->getObjCoefficients();
  const double* clbs = si->getColLower();
  const double* cubs = si->getColUpper();
  int ncol = si->getNumCols();
  std::cout << "Column info\n";
  for (int i = 0; i != ncol; i ++) {
    std::cout << i
              << " obj" << ": " << objs[i]
              << " lb" << ": " << clbs[i]
              << " ub" << ": " << cubs[i]
              << " int" << ": " << std::boolalpha << si->isInteger(i) << '\n';
  }

  const CoinPackedMatrix* m = si->getMatrixByRow();
  const double* rlbs = si->getRowLower();
  const double* rubs = si->getRowUpper();
  int nrow = si->getNumRows();
  std::cout << "Row info\n";
  for (int i = 0; i != nrow; i ++) {
    std::cout << i
              << " lb" << ": " << rlbs[i]
              << " ub" << ": " << rubs[i] << '\n';
  }
  std::cout << "matrix:\n";
  m->dumpMatrix();
}

void SolveProg(OsiSolverInterface* si, double greedy_obj, bool verbose) {
  if (verbose)
    ReportProg(si);

  if (HasInt(si)) {
    const char *argv[] = {"exchng", "-log", "0", "-solve","-quit"};
    int argc = 3;
    CbcModel model(*si);
    // ObjValueHandler handler(greedy_obj);
    CbcMain0(model);
    // model.passInEventHandler(&handler);
    CbcMain1(argc, argv, model, CbcCallBack);
    si->setColSolution(model.getColSolution());
    // if (verbose) {
    //   std::cout << "Greedy equivalent time: " << handler.time()
    //             << " and obj " << handler.obj()
    //             << " and found " << std::boolalpha << handler.found() << "\n";
    // }
  } else {
    // no ints, just solve 'initial lp relaxation'
    si->initialSolve();
  }

  if (verbose) {
    const double* soln = si->getColSolution();
    for (int i = 0; i != si->getNumCols(); i ++) {
      std::cout << "soln " << i << ": " << soln[i]
                << " integer: " << std::boolalpha << si->isInteger(i) << "\n";
    }
  }
}

void SolveProg(OsiSolverInterface* si) {
  SolveProg(si, si->getInfinity(), false);
}

void SolveProg(OsiSolverInterface* si, bool verbose) {
  SolveProg(si, si->getInfinity(), verbose);
}

void SolveProg(OsiSolverInterface* si, double greedy_obj) {
  SolveProg(si, greedy_obj, false);
}

bool HasInt(OsiSolverInterface* si) {
  int i = 0;
  for (i = 0; i != si->getNumCols(); i++) {
    if (si->isInteger(i)) {
      return true;
    }
  }
  return false;
}

}  // namespace cyclus
<commit_msg>reintroduce greedy handler<commit_after>#include "solver_factory.h"

#include <iostream>

#include "OsiClpSolverInterface.hpp"
#include "OsiCbcSolverInterface.hpp"
#include "CbcSolver.hpp"
#include "CoinTime.hpp"

#include "error.h"

namespace cyclus {

int CbcCallBack(CbcModel * model, int from) {
  int ret = 0;
  switch (from) {
  case 1:
  case 2:
    if (!model->status() && model->secondaryStatus())
      ret=1;
    break;
  case 3:
  case 4:
  case 5:
    break;
  }
  return ret;
}

ObjValueHandler::ObjValueHandler(double obj, double time, bool found)
  : obj_(obj),
    time_(time),
    found_(found) { };

ObjValueHandler::ObjValueHandler(double obj)
  : obj_(obj),
    time_(0),
    found_(false) { };

ObjValueHandler::~ObjValueHandler() { };

ObjValueHandler::ObjValueHandler(const ObjValueHandler& other): CbcEventHandler(other) {
  obj_ = other.obj();
  time_ = other.time();
  found_ = other.found();
}

ObjValueHandler& ObjValueHandler::operator=(const ObjValueHandler& other) {
  if (this != &other) {
    obj_ = other.obj();
    time_ = other.time();
    found_ = other.found();
    CbcEventHandler::operator=(other);
  }
  return *this;
}

CbcEventHandler* ObjValueHandler::clone() {
  return new ObjValueHandler(*this);
}

CbcEventHandler::CbcAction ObjValueHandler::event(CbcEvent e) {
  if (!found_ && (e == solution || e == heuristicSolution)) {
    const CbcModel* m = getModel();
    double cbcobj = m->getObjValue();
    if (cbcobj < obj_) {
      time_ = CoinCpuTime() -
              m->getDblParam(CbcModel::CbcStartSeconds);
      found_ = true;
    }
  }
  return noAction;
}

// 10800 s = 3 hrs * 60 min/hr * 60 s/min
#define CYCLUS_SOLVER_TIMEOUT 10800

SolverFactory::SolverFactory() : t_("cbc"), tmax_(CYCLUS_SOLVER_TIMEOUT) { }
SolverFactory::SolverFactory(std::string t) : t_(t), tmax_(CYCLUS_SOLVER_TIMEOUT) { }
SolverFactory::SolverFactory(std::string t, double tmax)
    : t_(t),
      tmax_(tmax) { }

OsiSolverInterface* SolverFactory::get() {
  if (t_ == "clp" || t_ == "cbc") {
    OsiClpSolverInterface* s = new OsiClpSolverInterface();
    s->getModelPtr()->setMaximumSeconds(tmax_);
    return s;
  } else {
    throw ValueError("invalid SolverFactory type '" + t_ + "'");
  }
}

void ReportProg(OsiSolverInterface* si) {
  const double* objs = si->getObjCoefficients();
  const double* clbs = si->getColLower();
  const double* cubs = si->getColUpper();
  int ncol = si->getNumCols();
  std::cout << "Column info\n";
  for (int i = 0; i != ncol; i ++) {
    std::cout << i
              << " obj" << ": " << objs[i]
              << " lb" << ": " << clbs[i]
              << " ub" << ": " << cubs[i]
              << " int" << ": " << std::boolalpha << si->isInteger(i) << '\n';
  }

  const CoinPackedMatrix* m = si->getMatrixByRow();
  const double* rlbs = si->getRowLower();
  const double* rubs = si->getRowUpper();
  int nrow = si->getNumRows();
  std::cout << "Row info\n";
  for (int i = 0; i != nrow; i ++) {
    std::cout << i
              << " lb" << ": " << rlbs[i]
              << " ub" << ": " << rubs[i] << '\n';
  }
  std::cout << "matrix:\n";
  m->dumpMatrix();
}

void SolveProg(OsiSolverInterface* si, double greedy_obj, bool verbose) {
  if (verbose)
    ReportProg(si);

  if (HasInt(si)) {
    const char *argv[] = {"exchng", "-log", "0", "-solve","-quit"};
    int argc = 3;
    CbcModel model(*si);
    ObjValueHandler handler(greedy_obj);
    CbcMain0(model);
    model.passInEventHandler(&handler);
    CbcMain1(argc, argv, model, CbcCallBack);
    si->setColSolution(model.getColSolution());
    if (verbose) {
      std::cout << "Greedy equivalent time: " << handler.time()
                << " and obj " << handler.obj()
                << " and found " << std::boolalpha << handler.found() << "\n";
    }
  } else {
    // no ints, just solve 'initial lp relaxation'
    si->initialSolve();
  }

  if (verbose) {
    const double* soln = si->getColSolution();
    for (int i = 0; i != si->getNumCols(); i ++) {
      std::cout << "soln " << i << ": " << soln[i]
                << " integer: " << std::boolalpha << si->isInteger(i) << "\n";
    }
  }
}

void SolveProg(OsiSolverInterface* si) {
  SolveProg(si, si->getInfinity(), false);
}

void SolveProg(OsiSolverInterface* si, bool verbose) {
  SolveProg(si, si->getInfinity(), verbose);
}

void SolveProg(OsiSolverInterface* si, double greedy_obj) {
  SolveProg(si, greedy_obj, false);
}

bool HasInt(OsiSolverInterface* si) {
  int i = 0;
  for (i = 0; i != si->getNumCols(); i++) {
    if (si->isInteger(i)) {
      return true;
    }
  }
  return false;
}

}  // namespace cyclus
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkExtractEdges.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
#include "vtkExtractEdges.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkDataSet.h"
#include "vtkEdgeTable.h"
#include "vtkGenericCell.h"
#include "vtkMergePoints.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"

vtkCxxRevisionMacro(vtkExtractEdges, "1.44");
vtkStandardNewMacro(vtkExtractEdges);

// Construct object.
vtkExtractEdges::vtkExtractEdges()
{
  this->Locator = NULL;
}

vtkExtractEdges::~vtkExtractEdges()
{
  if ( this->Locator )
    {
    this->Locator->UnRegister(this);
    this->Locator = NULL;
    }
}

// Generate feature edges for mesh
void vtkExtractEdges::Execute()
{
  vtkDataSet *input= this->GetInput();
  vtkPolyData *output= this->GetOutput();
  vtkPoints *newPts;
  vtkCellArray *newLines;
  vtkIdType numCells, cellNum, numPts, newId;
  int edgeNum, numEdgePts, numCellEdges;
  int i, abort = 0;
  vtkIdType pts[2];
  vtkIdType pt1 = 0, pt2;
  float *x;
  vtkEdgeTable *edgeTable;
  vtkGenericCell *cell;
  vtkCell *edge;
  vtkPointData *pd, *outPD;
  vtkCellData *cd, *outCD;

  vtkDebugMacro(<<"Executing edge extractor");

  //  Check input
  //
  numPts=input->GetNumberOfPoints();
  if ( (numCells=input->GetNumberOfCells()) < 1 || numPts < 1 )
    {
    vtkErrorMacro(<<"No input data!");
    return;
    }

  // Set up processing
  //
  edgeTable = vtkEdgeTable::New();
  edgeTable->InitEdgeInsertion(numPts);
  newPts = vtkPoints::New();
  newPts->Allocate(numPts);
  newLines = vtkCellArray::New();
  newLines->EstimateSize(numPts*4,2);

  pd = input->GetPointData();
  outPD = output->GetPointData();
  outPD->CopyAllocate(pd,numPts);

  cd = input->GetCellData();
  outCD = output->GetCellData();
  outCD->CopyAllocate(cd,numCells);

  cell = vtkGenericCell::New();

  // Get our locator for merging points
  //
  if ( this->Locator == NULL )
    {
    this->CreateDefaultLocator();
    }
  this->Locator->InitPointInsertion (newPts, input->GetBounds());

  // Loop over all cells, extracting non-visited edges.
  //
  int tenth = numCells/10 + 1;
  for (cellNum=0; cellNum < numCells && !abort; cellNum++ )
    {
    if ( ! (cellNum % tenth) ) //manage progress reports / early abort
      {
      this->UpdateProgress ((float)cellNum / numCells);
      abort = this->GetAbortExecute();
      }

    input->GetCell(cellNum,cell);
    numCellEdges = cell->GetNumberOfEdges();
    for (edgeNum=0; edgeNum < numCellEdges; edgeNum++ )
      {
      edge = cell->GetEdge(edgeNum);
      numEdgePts = edge->GetNumberOfPoints();

      for ( i=0; i < numEdgePts; i++, pt1=pt2, pts[0]=pts[1] )
        {
        pt2 = edge->PointIds->GetId(i);
        x = input->GetPoint(pt2);
        if ( this->Locator->InsertUniquePoint(x, pts[1]) )
          {
          outPD->CopyData (pd,pt2,pts[1]);
          }
        if ( i > 0 && edgeTable->IsEdge(pt1,pt2) == -1 )
          {
          edgeTable->InsertEdge(pt1, pt2);
          newId = newLines->InsertNextCell(2,pts);
          outCD->CopyData(cd, cellNum, newId);
          }
        }
      }//for all edges of cell
    }//for all cells

  vtkDebugMacro(<<"Created " << newLines->GetNumberOfCells() << " edges");

  //  Update ourselves.
  //
  edgeTable->Delete();
  cell->Delete();

  output->SetPoints(newPts);
  newPts->Delete();

  output->SetLines(newLines);
  newLines->Delete();

  output->Squeeze();
}

// Specify a spatial locator for merging points. By
// default an instance of vtkMergePoints is used.
void vtkExtractEdges::SetLocator(vtkPointLocator *locator)
{
  if ( this->Locator == locator )
    {
    return;
    }
  if ( this->Locator )
    {
    this->Locator->UnRegister(this);
    this->Locator = NULL;
    }
  if ( locator )
    {
    locator->Register(this);
    }
  this->Locator = locator;
  this->Modified();
}

void vtkExtractEdges::CreateDefaultLocator()
{
  if ( this->Locator == NULL )
    {
    vtkMergePoints *locator = vtkMergePoints::New();
    this->SetLocator(locator);
    locator->Delete();
    }
}

void vtkExtractEdges::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  if ( this->Locator )
    {
    os << indent << "Locator: " << this->Locator << "\n";
    }
  else
    {
    os << indent << "Locator: (none)\n";
    }
}

unsigned long int vtkExtractEdges::GetMTime()
{
  unsigned long mTime=this-> vtkDataSetToPolyDataFilter::GetMTime();
  unsigned long time;

  if ( this->Locator != NULL )
    {
    time = this->Locator->GetMTime();
    mTime = ( time > mTime ? time : mTime );
    }
  return mTime;
}

<commit_msg>ERR:Properly support extraction of higher-order edges<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkExtractEdges.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
#include "vtkExtractEdges.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkDataSet.h"
#include "vtkEdgeTable.h"
#include "vtkGenericCell.h"
#include "vtkMergePoints.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPolyData.h"

vtkCxxRevisionMacro(vtkExtractEdges, "1.45");
vtkStandardNewMacro(vtkExtractEdges);

// Construct object.
vtkExtractEdges::vtkExtractEdges()
{
  this->Locator = NULL;
}

vtkExtractEdges::~vtkExtractEdges()
{
  if ( this->Locator )
    {
    this->Locator->UnRegister(this);
    this->Locator = NULL;
    }
}

// Generate feature edges for mesh
void vtkExtractEdges::Execute()
{
  vtkDataSet *input= this->GetInput();
  vtkPolyData *output= this->GetOutput();
  vtkPoints *newPts;
  vtkCellArray *newLines;
  vtkIdType numCells, cellNum, numPts, newId;
  int edgeNum, numEdgePts, numCellEdges;
  int i, abort = 0;
  vtkIdType pts[2];
  vtkIdType pt1 = 0, pt2;
  float *x;
  vtkEdgeTable *edgeTable;
  vtkGenericCell *cell;
  vtkCell *edge;
  vtkPointData *pd, *outPD;
  vtkCellData *cd, *outCD;

  vtkDebugMacro(<<"Executing edge extractor");

  //  Check input
  //
  numPts=input->GetNumberOfPoints();
  if ( (numCells=input->GetNumberOfCells()) < 1 || numPts < 1 )
    {
    vtkErrorMacro(<<"No input data!");
    return;
    }

  // Set up processing
  //
  edgeTable = vtkEdgeTable::New();
  edgeTable->InitEdgeInsertion(numPts);
  newPts = vtkPoints::New();
  newPts->Allocate(numPts);
  newLines = vtkCellArray::New();
  newLines->EstimateSize(numPts*4,2);

  pd = input->GetPointData();
  outPD = output->GetPointData();
  outPD->CopyAllocate(pd,numPts);

  cd = input->GetCellData();
  outCD = output->GetCellData();
  outCD->CopyAllocate(cd,numCells);

  cell = vtkGenericCell::New();
  vtkIdList *edgeIds, *HEedgeIds=vtkIdList::New();
  vtkPoints *edgePts, *HEedgePts=vtkPoints::New();

  // Get our locator for merging points
  //
  if ( this->Locator == NULL )
    {
    this->CreateDefaultLocator();
    }
  this->Locator->InitPointInsertion (newPts, input->GetBounds());

  // Loop over all cells, extracting non-visited edges.
  //
  int tenth = numCells/10 + 1;
  for (cellNum=0; cellNum < numCells && !abort; cellNum++ )
    {
    if ( ! (cellNum % tenth) ) //manage progress reports / early abort
      {
      this->UpdateProgress ((float)cellNum / numCells);
      abort = this->GetAbortExecute();
      }

    input->GetCell(cellNum,cell);
    numCellEdges = cell->GetNumberOfEdges();
    for (edgeNum=0; edgeNum < numCellEdges; edgeNum++ )
      {
      edge = cell->GetEdge(edgeNum);
      numEdgePts = edge->GetNumberOfPoints();

      // Tessellate higher-order edges
      if ( ! edge->IsLinear() )
        {
        edge->Triangulate(0, HEedgeIds, HEedgePts);
        edgeIds = HEedgeIds;
        edgePts = HEedgePts;

        for ( i=0; i < (edgeIds->GetNumberOfIds()/2); i++ )
          {
          pt1 = edgeIds->GetId(2*i);
          pt2 = edgeIds->GetId(2*i+1);
          x = edgePts->GetPoint(2*i);
          if ( this->Locator->InsertUniquePoint(x, pts[0]) )
            {
            outPD->CopyData (pd,pt1,pts[0]);
            }
          x = edgePts->GetPoint(2*i+1);
          if ( this->Locator->InsertUniquePoint(x, pts[1]) )
            {
            outPD->CopyData (pd,pt2,pts[1]);
            }
          if ( edgeTable->IsEdge(pt1,pt2) == -1 )
            {
            edgeTable->InsertEdge(pt1, pt2);
            newId = newLines->InsertNextCell(2,pts);
            outCD->CopyData(cd, cellNum, newId);
            }
          }
        } //if non-linear edge

      else // linear edges
        {
        edgeIds = edge->PointIds;
        edgePts = edge->Points;

        for ( i=0; i < numEdgePts; i++, pt1=pt2, pts[0]=pts[1] )
          {
          pt2 = edgeIds->GetId(i);
          x = edgePts->GetPoint(pt2);
          if ( this->Locator->InsertUniquePoint(x, pts[1]) )
            {
            outPD->CopyData (pd,pt2,pts[1]);
            }
          if ( i > 0 && edgeTable->IsEdge(pt1,pt2) == -1 )
            {
            edgeTable->InsertEdge(pt1, pt2);
            newId = newLines->InsertNextCell(2,pts);
            outCD->CopyData(cd, cellNum, newId);
            }
          }//if linear edge
        }
      }//for all edges of cell
    }//for all cells

  vtkDebugMacro(<<"Created " << newLines->GetNumberOfCells() << " edges");

  //  Update ourselves.
  //
  HEedgeIds->Delete();
  HEedgePts->Delete();
  edgeTable->Delete();
  cell->Delete();

  output->SetPoints(newPts);
  newPts->Delete();

  output->SetLines(newLines);
  newLines->Delete();

  output->Squeeze();
}

// Specify a spatial locator for merging points. By
// default an instance of vtkMergePoints is used.
void vtkExtractEdges::SetLocator(vtkPointLocator *locator)
{
  if ( this->Locator == locator )
    {
    return;
    }
  if ( this->Locator )
    {
    this->Locator->UnRegister(this);
    this->Locator = NULL;
    }
  if ( locator )
    {
    locator->Register(this);
    }
  this->Locator = locator;
  this->Modified();
}

void vtkExtractEdges::CreateDefaultLocator()
{
  if ( this->Locator == NULL )
    {
    vtkMergePoints *locator = vtkMergePoints::New();
    this->SetLocator(locator);
    locator->Delete();
    }
}

void vtkExtractEdges::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  if ( this->Locator )
    {
    os << indent << "Locator: " << this->Locator << "\n";
    }
  else
    {
    os << indent << "Locator: (none)\n";
    }
}

unsigned long int vtkExtractEdges::GetMTime()
{
  unsigned long mTime=this-> vtkDataSetToPolyDataFilter::GetMTime();
  unsigned long time;

  if ( this->Locator != NULL )
    {
    time = this->Locator->GetMTime();
    mTime = ( time > mTime ? time : mTime );
    }
  return mTime;
}

<|endoftext|>


<commit_before>
#include "HuboRT/Manager.hpp"
#include <iostream>

extern "C" {
#include "HuboRT/Daemonizer_C.h"
#include "HuboCan/hubo_info_c.h"
}

int main(int argc, char* argv[])
{
    HuboRT::Manager mgr;

    mgr.create_all_ach_chans();
//    mgr.stop_all_processes();

//    mgr.register_new_proc("bogus:/home/grey/projects/HuboCan/bin/daemon_test::");

//    mgr.run_all_processes();

//    mgr.launch();

    return 0;
}
<commit_msg>testing actual manager<commit_after>
#include "HuboRT/Manager.hpp"
#include <iostream>

extern "C" {
#include "HuboRT/Daemonizer_C.h"
#include "HuboCan/hubo_info_c.h"
}

int main(int argc, char* argv[])
{
    HuboRT::Manager mgr;

    mgr.run();

//    mgr.create_all_ach_chans();
//    mgr.stop_all_processes();

//    mgr.register_new_proc("bogus:/home/grey/projects/HuboCan/bin/daemon_test::");

//    mgr.run_all_processes();

//    mgr.launch();

    return 0;
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkGaussianCubeReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
#include "vtkGaussianCubeReader.h"

#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkFloatArray.h"
#include "vtkIdTypeArray.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTransform.h"

#include <ctype.h>

vtkCxxRevisionMacro(vtkGaussianCubeReader, "1.15");
vtkStandardNewMacro(vtkGaussianCubeReader);

// Construct object with merging set to true.
vtkGaussianCubeReader::vtkGaussianCubeReader()
{
  this->FileName = NULL;
  this->Transform = vtkTransform::New();
  // Add the second output for the grid data

  this->SetNumberOfOutputPorts(2);
  vtkImageData *grid;
  grid = vtkImageData::New();
  grid->ReleaseData();
  this->GetExecutive()->SetOutputData(1, grid);
  grid->Delete();
}

vtkGaussianCubeReader::~vtkGaussianCubeReader()
{
  if (this->FileName)
    {
    delete [] this->FileName;
    }
  this->Transform->Delete();
  // must delete the second output added
}

int vtkGaussianCubeReader::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  FILE *fp;
  char Title[256];
  char data_name[256];
  double elements[16];
  int JN1, N1N2, n1, n2, n3, i, j, k;
  float tmp, *Cube_data;

  // Output 0 (the default is the polydata)
  // Output 1 will be the gridded Image data

  vtkImageData *grid = this->GetGridOutput();

  if (!this->FileName)
    {
    return 0;
    }

  if ((fp = fopen(this->FileName, "r")) == NULL)
    {
    vtkErrorMacro(<< "File " << this->FileName << " not found");
    return 0;
    }

  fgets(Title, 256, fp);
  if(strtok(Title, ":") != NULL)
    {
    if(strtok(NULL, ":") != NULL)
      {
      strcpy(data_name, strtok(NULL, ":"));
      fprintf(stderr,"label = %s\n", data_name);
      }
    }
  fgets(Title, 256, fp);

  // Read in number of atoms, x-origin, y-origin z-origin
  //
  fscanf(fp, "%d %lf %lf %lf", &(this->NumberOfAtoms), &elements[3],
         &elements[7], &elements[11]);
  if(this->NumberOfAtoms < 0 )
    {
    this->NumberOfAtoms = -this->NumberOfAtoms;
    }

  fscanf(fp, "%d %lf %lf %lf", &n1, &elements[0], &elements[4], &elements[8]);
  fscanf(fp, "%d %lf %lf %lf", &n2, &elements[1], &elements[5], &elements[9]);
  fscanf(fp, "%d %lf %lf %lf", &n3, &elements[2], &elements[6], &elements[10]);
  elements[12] = 0;
  elements[13] = 0;
  elements[14] = 0;
  elements[15] = 1;

  vtkDebugMacro(<< "Grid Size " << n1 << " " << n2 << " " << n3);

  Transform->SetMatrix(elements);
  Transform->Inverse();

  this->ReadMolecule(fp, output);

  vtkInformation *gridInfo = this->GetExecutive()->GetOutputInformation(1);
  gridInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
                0, n1-1, 0, n2-1, 0, n3-1);
  gridInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
                gridInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()),
                6);
  grid->SetExtent(
    gridInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));

  grid->SetOrigin(0, 0, 0);
  grid->SetSpacing(1, 1, 1);
  grid->SetScalarTypeToFloat();
  grid->AllocateScalars();

  grid->GetPointData()->GetScalars()->SetName("Gaussian Cube density");

  Cube_data = (float *)grid->GetPointData()->GetScalars()->GetVoidPointer(0);
  N1N2 = n1*n2;

  for(i = 0; i < n1; i++)
    {
    JN1 = 0;
    for(j = 0; j < n2; j++)
      {
      for(k = 0; k < n3; k++)
        {
        fscanf(fp,"%f", &tmp);
        Cube_data[k*N1N2 + JN1 + i] = tmp;
        }
      JN1 += n1;
      }
    }
  fclose(fp);

  return 1;
}

void vtkGaussianCubeReader::ReadSpecificMolecule(FILE* fp)
{
  int i, j;
  float x[3];
  float dummy;

  for(i = 0; i < this->NumberOfAtoms; i++)
    {
    fscanf(fp, "%d %f %f %f %f", &j, &dummy, x, x+1, x+2);
    this->Points->InsertNextPoint(x);
    this->AtomType->InsertNextValue(j-1);
    }
}

vtkImageData *vtkGaussianCubeReader::GetGridOutput()
{
  if (this->GetNumberOfOutputPorts() < 2)
    {
    return NULL;
    }
  return vtkImageData::SafeDownCast(
    this->GetExecutive()->GetOutputData(1));
}

void vtkGaussianCubeReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << "Filename: " << (this->FileName?this->FileName:"(none)") << "\n";

  os << "Tranform: ";
  if( this->Transform )
    {
    os << endl;
    this->Transform->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)\n";
    }
}

// Default implementation - copy information from first input to all outputs
int vtkGaussianCubeReader::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *vtkNotUsed(outputVector))
{
  // the set the information for the imagedat output
  vtkInformation *gridInfo = this->GetExecutive()->GetOutputInformation(1);

  FILE *fp;
  char Title[256];

  if (!this->FileName)
    {
    return 0;
    }

  if ((fp = fopen(this->FileName, "r")) == NULL)
    {
    vtkErrorMacro(<< "File " << this->FileName << " not found");
    return 0;
    }

  fgets(Title, 256, fp);
  fgets(Title, 256, fp);

  // Read in number of atoms, x-origin, y-origin z-origin
  double tmpd;
  int n1, n2, n3;
  fscanf(fp, "%d %lf %lf %lf", &n1, &tmpd, &tmpd, &tmpd);

  fscanf(fp, "%d %lf %lf %lf", &n1, &tmpd, &tmpd, &tmpd);
  fscanf(fp, "%d %lf %lf %lf", &n2, &tmpd, &tmpd, &tmpd);
  fscanf(fp, "%d %lf %lf %lf", &n3, &tmpd, &tmpd, &tmpd);

  vtkDebugMacro(<< "Grid Size " << n1 << " " << n2 << " " << n3);
  gridInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
                0, n1-1, 0, n2-1, 0, n3-1);
  gridInfo->Set(vtkDataObject::ORIGIN(), 0, 0, 0);
  gridInfo->Set(vtkDataObject::SPACING(), 1, 1, 1);

  fclose(fp);

  vtkDataObject::SetPointDataActiveScalarInfo(gridInfo, VTK_FLOAT, -1);
  return 1;
}

//----------------------------------------------------------------------------
int vtkGaussianCubeReader::FillOutputPortInformation(int port,
                                                     vtkInformation* info)
{
  if(port == 0)
    {
    return this->Superclass::FillOutputPortInformation(port, info);
    }
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkImageData");
  return 1;
}
<commit_msg>BUG: incorporating Jean Favre's changes on the ParaView-2-0 branch<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGaussianCubeReader.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

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

=========================================================================*/
#include "vtkGaussianCubeReader.h"

#include "vtkImageData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkFloatArray.h"
#include "vtkIdTypeArray.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTransform.h"

#include <ctype.h>

vtkCxxRevisionMacro(vtkGaussianCubeReader, "1.15.2.1");
vtkStandardNewMacro(vtkGaussianCubeReader);

// Construct object with merging set to true.
vtkGaussianCubeReader::vtkGaussianCubeReader()
{
  this->FileName = NULL;
  this->Transform = vtkTransform::New();
  // Add the second output for the grid data

  this->SetNumberOfOutputPorts(2);
  vtkImageData *grid;
  grid = vtkImageData::New();
  grid->ReleaseData();
  this->GetExecutive()->SetOutputData(1, grid);
  grid->Delete();
}

vtkGaussianCubeReader::~vtkGaussianCubeReader()
{
  if (this->FileName)
    {
    delete [] this->FileName;
    }
  this->Transform->Delete();
  // must delete the second output added
}

int vtkGaussianCubeReader::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  vtkInformation *outInfo = outputVector->GetInformationObject(0);
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  FILE *fp;
  char Title[256];
  char data_name[256];
  double elements[16];
  int JN1, N1N2, n1, n2, n3, i, j, k;
  float tmp, *Cube_data;

  // Output 0 (the default is the polydata)
  // Output 1 will be the gridded Image data

  vtkImageData *grid = this->GetGridOutput();

  if (!this->FileName)
    {
    return 0;
    }

  if ((fp = fopen(this->FileName, "r")) == NULL)
    {
    vtkErrorMacro(<< "File " << this->FileName << " not found");
    return 0;
    }

  fgets(Title, 256, fp);
  if(strtok(Title, ":") != NULL)
    {
    if(strtok(NULL, ":") != NULL)
      {
      strcpy(data_name, strtok(NULL, ":"));
      fprintf(stderr,"label = %s\n", data_name);
      }
    }
  fgets(Title, 256, fp);

  // Read in number of atoms, x-origin, y-origin z-origin
  //
  fscanf(fp, "%d %lf %lf %lf", &(this->NumberOfAtoms), &elements[3],
         &elements[7], &elements[11]);
  if(this->NumberOfAtoms < 0 )
    {
    this->NumberOfAtoms = -this->NumberOfAtoms;
    }

  fscanf(fp, "%d %lf %lf %lf", &n1, &elements[0], &elements[4], &elements[8]);
  fscanf(fp, "%d %lf %lf %lf", &n2, &elements[1], &elements[5], &elements[9]);
  fscanf(fp, "%d %lf %lf %lf", &n3, &elements[2], &elements[6], &elements[10]);
  elements[12] = 0;
  elements[13] = 0;
  elements[14] = 0;
  elements[15] = 1;

  vtkDebugMacro(<< "Grid Size " << n1 << " " << n2 << " " << n3);

  Transform->SetMatrix(elements);
  Transform->Inverse();

  this->ReadMolecule(fp, output);

  vtkInformation *gridInfo = this->GetExecutive()->GetOutputInformation(1);
  gridInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
                0, n1-1, 0, n2-1, 0, n3-1);
  gridInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_EXTENT(),
                gridInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()),
                6);
  grid->SetExtent(
    gridInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()));

  grid->SetOrigin(0, 0, 0);
  grid->SetSpacing(1, 1, 1);
  grid->SetScalarTypeToFloat();
  grid->AllocateScalars();

  grid->GetPointData()->GetScalars()->SetName(Title);

  Cube_data = (float *)grid->GetPointData()->GetScalars()->GetVoidPointer(0);
  N1N2 = n1*n2;

  for(i = 0; i < n1; i++)
    {
    JN1 = 0;
    for(j = 0; j < n2; j++)
      {
      for(k = 0; k < n3; k++)
        {
        fscanf(fp,"%f", &tmp);
        Cube_data[k*N1N2 + JN1 + i] = tmp;
        }
      JN1 += n1;
      }
    }
  fclose(fp);

  return 1;
}

void vtkGaussianCubeReader::ReadSpecificMolecule(FILE* fp)
{
  int i, j;
  float x[3];
  float dummy;

  for(i = 0; i < this->NumberOfAtoms; i++)
    {
    fscanf(fp, "%d %f %f %f %f", &j, &dummy, x, x+1, x+2);
    this->Transfom->TransformPoint(x, x);
    this->Points->InsertNextPoint(x);
    this->AtomType->InsertNextValue(j-1);
    }
}

vtkImageData *vtkGaussianCubeReader::GetGridOutput()
{
  if (this->GetNumberOfOutputPorts() < 2)
    {
    return NULL;
    }
  return vtkImageData::SafeDownCast(
    this->GetExecutive()->GetOutputData(1));
}

void vtkGaussianCubeReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << "Filename: " << (this->FileName?this->FileName:"(none)") << "\n";

  os << "Tranform: ";
  if( this->Transform )
    {
    os << endl;
    this->Transform->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)\n";
    }
}

// Default implementation - copy information from first input to all outputs
int vtkGaussianCubeReader::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *vtkNotUsed(outputVector))
{
  // the set the information for the imagedat output
  vtkInformation *gridInfo = this->GetExecutive()->GetOutputInformation(1);

  FILE *fp;
  char Title[256];

  if (!this->FileName)
    {
    return 0;
    }

  if ((fp = fopen(this->FileName, "r")) == NULL)
    {
    vtkErrorMacro(<< "File " << this->FileName << " not found");
    return 0;
    }

  fgets(Title, 256, fp);
  fgets(Title, 256, fp);

  // Read in number of atoms, x-origin, y-origin z-origin
  double tmpd;
  int n1, n2, n3;
  fscanf(fp, "%d %lf %lf %lf", &n1, &tmpd, &tmpd, &tmpd);

  fscanf(fp, "%d %lf %lf %lf", &n1, &tmpd, &tmpd, &tmpd);
  fscanf(fp, "%d %lf %lf %lf", &n2, &tmpd, &tmpd, &tmpd);
  fscanf(fp, "%d %lf %lf %lf", &n3, &tmpd, &tmpd, &tmpd);

  vtkDebugMacro(<< "Grid Size " << n1 << " " << n2 << " " << n3);
  gridInfo->Set(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(),
                0, n1-1, 0, n2-1, 0, n3-1);
  gridInfo->Set(vtkDataObject::ORIGIN(), 0, 0, 0);
  gridInfo->Set(vtkDataObject::SPACING(), 1, 1, 1);

  fclose(fp);

  vtkDataObject::SetPointDataActiveScalarInfo(gridInfo, VTK_FLOAT, -1);
  return 1;
}

//----------------------------------------------------------------------------
int vtkGaussianCubeReader::FillOutputPortInformation(int port,
                                                     vtkInformation* info)
{
  if(port == 0)
    {
    return this->Superclass::FillOutputPortInformation(port, info);
    }
  info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkImageData");
  return 1;
}
<|endoftext|>


<commit_before>
#include "container.h"

#include "../utilities.h"
#include "../craft.h"

// public

std::string Container::contents_to_string() const
{
	// The calling function could construct the beginning of the sentence, like
	// "You have " or "The chest contains ".

	if (contents.size() == 0)
	{
		return "";
	}

	std::stringstream output;

	// record an iterator to the last item
	const auto last_it = contents.end()--;

	for (std::multimap<std::string, std::shared_ptr<Item>>::const_iterator it = contents.begin();
		it != contents.end(); ++it)
	{
		output << " ";

		// if the item is stackable
		if (const std::shared_ptr<Stackable> stackable = U::convert_to<Stackable>(it->second))
		{
			if (stackable->amount != 1) // and the amount is != 1
			{
				output << stackable->amount << " " << U::get_plural_for(stackable->name);
			}
		}
		else // the item is not stackable
		{
			output << U::get_article_for(it->second->name) << " " << it->second->name;
		}

		// append a period or a comma
		output << ((it == last_it) ? "." : ", ");
	}

	return output.str();
}

const std::multimap<std::string, std::shared_ptr<Item>> & Container::get_contents() const
{
	return contents;
}

bool Container::contains(const std::string & item_id) const
{
	// return a boolean indicating if chest contains at least one instance of the specified item
	return this->contents.find(item_id) != contents.cend();
}
bool Container::contains(const std::string & item_id, const unsigned & count) const
{
	const std::multimap<std::string, std::shared_ptr<Item>>::const_iterator item_it = contents.find(item_id);

	// if the item does not exist in the contents
	if (item_it == contents.cend()) return false;

	// if the item is stackable
	if (const std::shared_ptr<Stackable> stackable = U::convert_to<Stackable>(item_it->second))
	{
		// test if the present amount is greater than or equal to the count
		return stackable->amount >= count;
	}
	else // the item is not stackable
	{
		// test if at least [count] instances exist
		return contents.count(item_id) >= count;
	}
}

void Container::insert(const std::shared_ptr<Item> & item)
{
	if (U::is<Stackable>(item) && contains(item->name)) // if the item is stackable and already exists in the chest
	{
		// increment the existing item in the chest
		U::convert_to<Stackable>(contents.find(item->name)->second)->amount++;
	}
	else // the item is either not stackable, or is not in the chest
	{
		contents.insert(make_pair(item->name, item));
	}
}
std::shared_ptr<Item> Container::erase(const std::string & item_id)
{
	// get an iterator to the item in question
	const std::multimap<std::string, std::shared_ptr<Item>>::iterator item_it = contents.find(item_id);

	// if the item does not exist to take, return a null pointer
	if (item_it == contents.cend()) return nullptr;

	// create a new shared_ptr to the stored item
	std::shared_ptr<Item> item = contents.find(item_id)->second;

	// if the item is a stackable type
	if (std::shared_ptr<Stackable> stackable = U::convert_to<Stackable>(item))
	{
		// count one less item in storage
		stackable->amount--;

		// if there are no items remaining in storage
		if (stackable->amount < 1)
		{
			// destroy the container's reference to the item
			contents.erase(item_id);
		}

		// return a new instance of the stackable item
		return Craft::make(item_id);
	}
	else // the item is not stackab.e
	{
		// destroy the container's reference to the item
		contents.erase(item_id);

		// return the local shared_ptr to the item
		return item;
	}
}
void Container::erase(const std::string & item_id, const unsigned & count)
{
	// get an iterator to the item in question
	const std::multimap<std::string, std::shared_ptr<Item>>::iterator item_it = contents.find(item_id);

	// if the item is not present in the chest, remove the item
	if (item_it == contents.cend()) return;

	// if the item is stackable
	if (std::shared_ptr<Stackable> stackable = U::convert_to<Stackable>(item_it->second))
	{
		// erase the amount required
		stackable->amount -= count;

		// if the container no longer contains at least one instance of the item
		if (stackable->amount < 1)
		{
			// erase the container's reference to the item
			contents.erase(item_id);
		}
	}
	else // the item is not stackable
	{
		// for as many times as specified
		for (unsigned i = 0; i < count; ++i)
		{
			// erase the container's reference to the item
			contents.erase(item_id);
		}
	}
}

// protected

void Container::set_contents(const std::multimap<std::string, std::shared_ptr<Item>> & set_contents)
{
	contents = set_contents;
}
<commit_msg>fix singular words in inventory printouts<commit_after>
#include "container.h"

#include "../utilities.h"
#include "../craft.h"

// public

std::string Container::contents_to_string() const
{
	// The calling function could construct the beginning of the sentence, like
	// "You have " or "The chest contains ".

	if (contents.size() == 0)
	{
		return "";
	}

	std::stringstream output;
	output << " ";

	// record an iterator to the last item
	const auto last_it = contents.end()--;

	for (std::multimap<std::string, std::shared_ptr<Item>>::const_iterator it = contents.begin();
		it != contents.end(); ++it)
	{

		// if the item is stackable
		if (const std::shared_ptr<Stackable> stackable = U::convert_to<Stackable>(it->second))
		{
			if (stackable->amount != 1) // and the amount is != 1
			{
				output << stackable->amount << " " << U::get_plural_for(stackable->name);
			}
			else
			{
				output << U::get_article_for(it->second->name) << " " << it->second->name; // this is duplicated below, but I'm not sure how to fix this
			}
		}
		else // the item is not stackable
		{
			output << U::get_article_for(it->second->name) << " " << it->second->name;
		}

		// append a period or a comma
		output << ((it == last_it) ? "." : ", ");
	}

	return output.str();
}

const std::multimap<std::string, std::shared_ptr<Item>> & Container::get_contents() const
{
	return contents;
}

bool Container::contains(const std::string & item_id) const
{
	// return a boolean indicating if chest contains at least one instance of the specified item
	return this->contents.find(item_id) != contents.cend();
}
bool Container::contains(const std::string & item_id, const unsigned & count) const
{
	const std::multimap<std::string, std::shared_ptr<Item>>::const_iterator item_it = contents.find(item_id);

	// if the item does not exist in the contents
	if (item_it == contents.cend()) return false;

	// if the item is stackable
	if (const std::shared_ptr<Stackable> stackable = U::convert_to<Stackable>(item_it->second))
	{
		// test if the present amount is greater than or equal to the count
		return stackable->amount >= count;
	}
	else // the item is not stackable
	{
		// test if at least [count] instances exist
		return contents.count(item_id) >= count;
	}
}

void Container::insert(const std::shared_ptr<Item> & item)
{
	if (U::is<Stackable>(item) && contains(item->name)) // if the item is stackable and already exists in the chest
	{
		// increment the existing item in the chest
		U::convert_to<Stackable>(contents.find(item->name)->second)->amount++;
	}
	else // the item is either not stackable, or is not in the chest
	{
		contents.insert(make_pair(item->name, item));
	}
}
std::shared_ptr<Item> Container::erase(const std::string & item_id)
{
	// get an iterator to the item in question
	const std::multimap<std::string, std::shared_ptr<Item>>::iterator item_it = contents.find(item_id);

	// if the item does not exist to take, return a null pointer
	if (item_it == contents.cend()) return nullptr;

	// create a new shared_ptr to the stored item
	std::shared_ptr<Item> item = contents.find(item_id)->second;

	// if the item is a stackable type
	if (std::shared_ptr<Stackable> stackable = U::convert_to<Stackable>(item))
	{
		// count one less item in storage
		stackable->amount--;

		// if there are no items remaining in storage
		if (stackable->amount < 1)
		{
			// destroy the container's reference to the item
			contents.erase(item_id);
		}

		// return a new instance of the stackable item
		return Craft::make(item_id);
	}
	else // the item is not stackab.e
	{
		// destroy the container's reference to the item
		contents.erase(item_id);

		// return the local shared_ptr to the item
		return item;
	}
}
void Container::erase(const std::string & item_id, const unsigned & count)
{
	// get an iterator to the item in question
	const std::multimap<std::string, std::shared_ptr<Item>>::iterator item_it = contents.find(item_id);

	// if the item is not present in the chest, remove the item
	if (item_it == contents.cend()) return;

	// if the item is stackable
	if (std::shared_ptr<Stackable> stackable = U::convert_to<Stackable>(item_it->second))
	{
		// erase the amount required
		stackable->amount -= count;

		// if the container no longer contains at least one instance of the item
		if (stackable->amount < 1)
		{
			// erase the container's reference to the item
			contents.erase(item_id);
		}
	}
	else // the item is not stackable
	{
		// for as many times as specified
		for (unsigned i = 0; i < count; ++i)
		{
			// erase the container's reference to the item
			contents.erase(item_id);
		}
	}
}

// protected

void Container::set_contents(const std::multimap<std::string, std::shared_ptr<Item>> & set_contents)
{
	contents = set_contents;
}
<|endoftext|>


<commit_before>#include "NamedEvent.h"
#include "Poco/Exception.h"
#include <cstring>

int luaopen_poco_namedevent(lua_State* L)
{
	return LuaPoco::loadConstructor(L, LuaPoco::NamedEventUserdata::NamedEvent);
}

namespace LuaPoco
{

NamedEventUserdata::NamedEventUserdata(const std::string& name) :
	mNamedEvent(name)
{
}

NamedEventUserdata::~NamedEventUserdata()
{
}

UserdataType NamedEventUserdata::getType()
{
	return Userdata_NamedEvent;
}

// register metatable for this class
bool NamedEventUserdata::registerNamedEvent(lua_State* L)
{
	luaL_newmetatable(L, "Poco.NamedEvent.metatable");
	lua_pushvalue(L, -1);
	lua_setfield(L, -2, "__index");
	lua_pushcfunction(L, metamethod__gc);
	lua_setfield(L, -2, "__gc");
	lua_pushcfunction(L, metamethod__tostring);
	lua_setfield(L, -2, "__tostring");

	lua_pushstring(L, "Poco.NamedEvent.metatable");
	lua_setfield(L, -2, "poco.userdata");

	// methods
	lua_pushcfunction(L, set);
	lua_setfield(L, -2, "set");
	lua_pushcfunction(L, wait);
	lua_setfield(L, -2, "wait");
	lua_pop(L, 1);

	return true;
}

int NamedEventUserdata::NamedEvent(lua_State* L)
{
	const char* name = luaL_checkstring(L, 1);

	void* ud = lua_newuserdata(L, sizeof(NamedEventUserdata));
	luaL_getmetatable(L, "Poco.NamedEvent.metatable");
	lua_setmetatable(L, -2);

	NamedEventUserdata* neud = new(ud) NamedEventUserdata(name);
	return 1;
}

// metamethod infrastructure
int NamedEventUserdata::metamethod__gc(lua_State* L)
{
	NamedEventUserdata* neud = reinterpret_cast<NamedEventUserdata*>(
		luaL_checkudata(L, 1, "Poco.NamedEvent.metatable"));
	neud->~NamedEventUserdata();

	return 0;
}

int NamedEventUserdata::metamethod__tostring(lua_State* L)
{
	NamedEventUserdata* neud = reinterpret_cast<NamedEventUserdata*>(
		luaL_checkudata(L, 1, "Poco.NamedEvent.metatable"));

	lua_pushfstring(L, "Poco.NamedEvent (%p)", reinterpret_cast<void*>(neud));
	return 1;
}

// userdata methods
int NamedEventUserdata::set(lua_State* L)
{
	NamedEventUserdata* neud = reinterpret_cast<NamedEventUserdata*>(
		luaL_checkudata(L, 1, "Poco.NamedEvent.metatable"));

	neud->mNamedEvent.set();

	return 0;
}

int NamedEventUserdata::wait(lua_State* L)
{
	NamedEventUserdata* neud = reinterpret_cast<NamedEventUserdata*>(
		luaL_checkudata(L, 1, "Poco.NamedEvent.metatable"));

	neud->mNamedEvent.wait();

	return 0;
}

} // LuaPoco
<commit_msg>ldoc for namedevent<commit_after>/// Global synchronization object for one process to signal another of an event.
// Note: namedevent is always autoresetting.
//
// Note: There should not be more than one instance of namedevent for a given name in a process. Otherwise, the instances may interfere with each other.
// @module namedevent

#include "NamedEvent.h"
#include "Poco/Exception.h"
#include <cstring>

int luaopen_poco_namedevent(lua_State* L)
{
	return LuaPoco::loadConstructor(L, LuaPoco::NamedEventUserdata::NamedEvent);
}

namespace LuaPoco
{

NamedEventUserdata::NamedEventUserdata(const std::string& name) :
	mNamedEvent(name)
{
}

NamedEventUserdata::~NamedEventUserdata()
{
}

UserdataType NamedEventUserdata::getType()
{
	return Userdata_NamedEvent;
}

// register metatable for this class
bool NamedEventUserdata::registerNamedEvent(lua_State* L)
{
	luaL_newmetatable(L, "Poco.NamedEvent.metatable");
	lua_pushvalue(L, -1);
	lua_setfield(L, -2, "__index");
	lua_pushcfunction(L, metamethod__gc);
	lua_setfield(L, -2, "__gc");
	lua_pushcfunction(L, metamethod__tostring);
	lua_setfield(L, -2, "__tostring");

	lua_pushstring(L, "Poco.NamedEvent.metatable");
	lua_setfield(L, -2, "poco.userdata");

	// methods
	lua_pushcfunction(L, set);
	lua_setfield(L, -2, "set");
	lua_pushcfunction(L, wait);
	lua_setfield(L, -2, "wait");
	lua_pop(L, 1);

	return true;
}

/// constructs a new namedevent userdata.
// @string name global event name.
// @return userdata.
// @function new

int NamedEventUserdata::NamedEvent(lua_State* L)
{
	const char* name = luaL_checkstring(L, 1);

	void* ud = lua_newuserdata(L, sizeof(NamedEventUserdata));
	luaL_getmetatable(L, "Poco.NamedEvent.metatable");
	lua_setmetatable(L, -2);

	NamedEventUserdata* neud = new(ud) NamedEventUserdata(name);
	return 1;
}

///
// @type namedevent

// metamethod infrastructure
int NamedEventUserdata::metamethod__gc(lua_State* L)
{
	NamedEventUserdata* neud = reinterpret_cast<NamedEventUserdata*>(
		luaL_checkudata(L, 1, "Poco.NamedEvent.metatable"));
	neud->~NamedEventUserdata();

	return 0;
}

int NamedEventUserdata::metamethod__tostring(lua_State* L)
{
	NamedEventUserdata* neud = reinterpret_cast<NamedEventUserdata*>(
		luaL_checkudata(L, 1, "Poco.NamedEvent.metatable"));

	lua_pushfstring(L, "Poco.NamedEvent (%p)", reinterpret_cast<void*>(neud));
	return 1;
}

// userdata methods

/// Signals the event.
// The process waiting for the event can resume execution.
// @function set
int NamedEventUserdata::set(lua_State* L)
{
	NamedEventUserdata* neud = reinterpret_cast<NamedEventUserdata*>(
		luaL_checkudata(L, 1, "Poco.NamedEvent.metatable"));

	neud->mNamedEvent.set();

	return 0;
}

/// Waits for the event to become signaled.
// Blocks the process until the event has become signaled.
// @function wait
int NamedEventUserdata::wait(lua_State* L)
{
	NamedEventUserdata* neud = reinterpret_cast<NamedEventUserdata*>(
		luaL_checkudata(L, 1, "Poco.NamedEvent.metatable"));

	neud->mNamedEvent.wait();

	return 0;
}

} // LuaPoco
<|endoftext|>