<commit_before>///////////////////////////////////////////////////////////////////////////////
//
// File MatrixKey.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Definition of MatrixKey based on StdMatrixKey
//
///////////////////////////////////////////////////////////////////////////////

#include <LocalRegions/LocalRegions.h>
#include <LocalRegions/MatrixKey.h>

namespace Nektar
{
    namespace LocalRegions
    {
        MatrixKey::MatrixKey(const StdRegions::MatrixType matrixType,
                             const StdRegions::ExpansionType expansionType,
                             const StdRegions::StdExpansion &stdExpansion,
                             LibUtilities::PointsType nodalType)
        {
            m_stdMatKey =  MemoryManager<StdRegions::StdMatrixKey>::AllocateSharedPtr(matrixType,
                                                                                expansionType,
                                                                                stdExpansion,
                                                                                nodalType);
            m_metricinfo  = stdExpansion.GetMetricInfo();
        }

        MatrixKey::MatrixKey(StdRegions::MatrixType matrixType,
                             StdRegions::ExpansionType expansionType,
                             StdRegions::StdExpansion &stdExpansion,
                             NekDouble    scalefactor,
                             LibUtilities::PointsType nodalType)
        {
            m_stdMatKey =  MemoryManager<StdRegions::StdMatrixKey>::AllocateSharedPtr(matrixType,
                                                                                expansionType,
                                                                                stdExpansion,
                                                                                scalefactor,
                                                                                nodalType);

            m_metricinfo  = stdExpansion.GetMetricInfo();
        }

        MatrixKey::MatrixKey(StdRegions::MatrixType matrixType,
                             StdRegions::ExpansionType expansionType,
                             StdRegions::StdExpansion &stdExpansion,
                             NekDouble    scalefactor,
                             NekDouble    constant,
                             LibUtilities::PointsType nodalType)
        {
            m_stdMatKey =  MemoryManager<StdRegions::StdMatrixKey>::AllocateSharedPtr(matrixType,
                                                                                expansionType,
                                                                                stdExpansion,
                                                                                scalefactor,
                                                                                constant,
                                                                                nodalType);

            m_metricinfo  = stdExpansion.GetMetricInfo();
        }

        MatrixKey::MatrixKey(const StdRegions::MatrixType matrixType,
                             const StdRegions::ExpansionType expansionType,
                             const StdRegions::StdExpansion &stdExpansion,
                             const Array<OneD, NekDouble>& constants,
                             const Array<OneD, Array<OneD,NekDouble> >& varcoeffs,
                             LibUtilities::PointsType nodalType)
        {
            m_stdMatKey =  MemoryManager<StdRegions::StdMatrixKey>::AllocateSharedPtr(matrixType,
                                                                                expansionType,
                                                                                stdExpansion,
                                                                                constants,
                                                                                varcoeffs,
                                                                                nodalType);

            m_metricinfo  = stdExpansion.GetMetricInfo();
        }

        bool MatrixKey::opLess::operator()(const MatrixKey &lhs, const MatrixKey &rhs) const
        {
            {
                return (lhs.GetMatrixType() < rhs.GetMatrixType());
            }
        }

        bool operator<(const MatrixKey &lhs, const MatrixKey &rhs)
        {
            if( *(lhs.m_metricinfo) < *(rhs.m_metricinfo) )
            {
                return true;
            }

            if( *(rhs.m_metricinfo) < *(lhs.m_metricinfo) )
            {
                return false;
            }

            bool returnval = (*lhs.GetStdMatKey() < *rhs.GetStdMatKey());

            return returnval;
        }

        std::ostream& operator<<(std::ostream& os, const MatrixKey& rhs)
        {
            os << *rhs.GetStdMatKey();

            return os;
        }
    }
}

/**
* $Log: MatrixKey.cpp,v $
* Revision 1.20  2008/11/19 16:46:43  pvos
* Fixed minor bug
*
* Revision 1.19  2008/11/19 16:01:41  pvos
* Added functionality for variable Laplacian coeffcients
*
* Revision 1.18  2008/07/09 11:39:47  sherwin
* Removed m_scalefactor and made operator< dependent upon StdMatKey
*
* Revision 1.17  2008/06/02 23:33:46  ehan
* Fixed warning : no new line at end of file
*
* Revision 1.16  2008/05/30 00:33:48  delisi
* Renamed StdRegions::ShapeType to StdRegions::ExpansionType.
*
* Revision 1.15  2008/05/29 01:02:13  bnelson
* Added precompiled header support.
*
* Revision 1.14  2007/12/17 13:04:29  sherwin
* Modified GenMatrix to take a StdMatrixKey and removed m_constant from MatrixKey
*
* Revision 1.13  2007/11/20 16:28:45  sherwin
* Added terms for UDG Helmholtz solver
*
* Revision 1.12  2007/07/28 05:09:32  sherwin
* Fixed version with updated MemoryManager
*
* Revision 1.11  2007/07/26 02:39:21  bnelson
* Fixed Visual C++ compiler errors when compiling in release mode.
*
* Revision 1.10  2007/07/20 00:45:50  bnelson
* Replaced boost::shared_ptr with Nektar::ptr
*
* Revision 1.9  2007/07/12 12:52:58  sherwin
* Updated to have a helmholtz matrix
*
* Revision 1.8  2007/07/10 17:17:22  sherwin
* Introduced Scaled Matrices into the MatrixManager
*
* Revision 1.7  2007/05/27 16:10:28  bnelson
* Update to new Array type.
*
* Revision 1.6  2007/04/08 03:33:30  jfrazier
* Minor reformatting and fixing SharedArray usage.
*
* Revision 1.5  2007/04/04 21:49:23  sherwin
* Update for SharedArray
*
* Revision 1.4  2007/03/20 09:13:37  kirby
* new geomfactor routines; update for metricinfo; update style
*
* Revision 1.3  2007/03/09 20:41:50  jfrazier
* *** empty log message ***
*
* Revision 1.2  2007/03/05 08:06:07  sherwin
* Updated to use MemoryManager
*
* Revision 1.1  2007/03/04 20:42:14  sherwin
* Keys for matrix managers
*
***/
<commit_msg>Minor update<commit_after>///////////////////////////////////////////////////////////////////////////////
//
// File MatrixKey.cpp
//
// For more information, please see: http://www.nektar.info
//
// The MIT License
//
// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
// Department of Aeronautics, Imperial College London (UK), and Scientific
// Computing and Imaging Institute, University of Utah (USA).
//
// License for the specific language governing rights and limitations under
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Definition of MatrixKey based on StdMatrixKey
//
///////////////////////////////////////////////////////////////////////////////

#include <LocalRegions/LocalRegions.h>
#include <LocalRegions/MatrixKey.h>

namespace Nektar
{
    namespace LocalRegions
    {
        MatrixKey::MatrixKey(const StdRegions::MatrixType matrixType,
                             const StdRegions::ExpansionType expansionType,
                             const StdRegions::StdExpansion &stdExpansion,
                             LibUtilities::PointsType nodalType)
        {
            m_stdMatKey =  MemoryManager<StdRegions::StdMatrixKey>::AllocateSharedPtr(matrixType,
                                                                                expansionType,
                                                                                stdExpansion,
                                                                                nodalType);
            m_metricinfo  = stdExpansion.GetMetricInfo();
        }

        MatrixKey::MatrixKey(StdRegions::MatrixType matrixType,
                             StdRegions::ExpansionType expansionType,
                             StdRegions::StdExpansion &stdExpansion,
                             NekDouble    scalefactor,
                             LibUtilities::PointsType nodalType)
        {
            m_stdMatKey =  MemoryManager<StdRegions::StdMatrixKey>::AllocateSharedPtr(matrixType,
                                                                                expansionType,
                                                                                stdExpansion,
                                                                                scalefactor,
                                                                                nodalType);

            m_metricinfo  = stdExpansion.GetMetricInfo();
        }

        MatrixKey::MatrixKey(StdRegions::MatrixType matrixType,
                             StdRegions::ExpansionType expansionType,
                             StdRegions::StdExpansion &stdExpansion,
                             NekDouble    scalefactor,
                             NekDouble    constant,
                             LibUtilities::PointsType nodalType)
        {
            m_stdMatKey =  MemoryManager<StdRegions::StdMatrixKey>::AllocateSharedPtr(matrixType,
                                                                                expansionType,
                                                                                stdExpansion,
                                                                                scalefactor,
                                                                                constant,
                                                                                nodalType);

            m_metricinfo  = stdExpansion.GetMetricInfo();
        }

        MatrixKey::MatrixKey(const StdRegions::MatrixType matrixType,
                             const StdRegions::ExpansionType expansionType,
                             const StdRegions::StdExpansion &stdExpansion,
                             const Array<OneD, NekDouble>& constants,
                             const Array<OneD, Array<OneD,NekDouble> >& varcoeffs,
                             LibUtilities::PointsType nodalType)
        {
            m_stdMatKey =  MemoryManager<StdRegions::StdMatrixKey>::AllocateSharedPtr(matrixType,
                                                                                expansionType,
                                                                                stdExpansion,
                                                                                constants,
                                                                                varcoeffs,
                                                                                nodalType);

            m_metricinfo  = stdExpansion.GetMetricInfo();
        }

        bool MatrixKey::opLess::operator()(const MatrixKey &lhs, const MatrixKey &rhs) const
        {
            {
                return (lhs.GetMatrixType() < rhs.GetMatrixType());
            }
        }

        bool operator<(const MatrixKey &lhs, const MatrixKey &rhs)
        {
//             if( *(lhs.m_metricinfo) < *(rhs.m_metricinfo) )
//             {
//                 return true;
//             }

//             if( *(rhs.m_metricinfo) < *(lhs.m_metricinfo) )
//             {
//                 return false;
//             }

            if(lhs.m_metricinfo.get() < rhs.m_metricinfo.get())
            {
                return true;
            }

            if(lhs.m_metricinfo.get() > rhs.m_metricinfo.get())
            {
                return false;
            }

            bool returnval = (*lhs.GetStdMatKey() < *rhs.GetStdMatKey());

            return returnval;
        }

        std::ostream& operator<<(std::ostream& os, const MatrixKey& rhs)
        {
            os << *rhs.GetStdMatKey();

            return os;
        }
    }
}

/**
* $Log: MatrixKey.cpp,v $
* Revision 1.21  2008/12/16 14:09:41  pvos
* Performance updates
*
* Revision 1.20  2008/11/19 16:46:43  pvos
* Fixed minor bug
*
* Revision 1.19  2008/11/19 16:01:41  pvos
* Added functionality for variable Laplacian coeffcients
*
* Revision 1.18  2008/07/09 11:39:47  sherwin
* Removed m_scalefactor and made operator< dependent upon StdMatKey
*
* Revision 1.17  2008/06/02 23:33:46  ehan
* Fixed warning : no new line at end of file
*
* Revision 1.16  2008/05/30 00:33:48  delisi
* Renamed StdRegions::ShapeType to StdRegions::ExpansionType.
*
* Revision 1.15  2008/05/29 01:02:13  bnelson
* Added precompiled header support.
*
* Revision 1.14  2007/12/17 13:04:29  sherwin
* Modified GenMatrix to take a StdMatrixKey and removed m_constant from MatrixKey
*
* Revision 1.13  2007/11/20 16:28:45  sherwin
* Added terms for UDG Helmholtz solver
*
* Revision 1.12  2007/07/28 05:09:32  sherwin
* Fixed version with updated MemoryManager
*
* Revision 1.11  2007/07/26 02:39:21  bnelson
* Fixed Visual C++ compiler errors when compiling in release mode.
*
* Revision 1.10  2007/07/20 00:45:50  bnelson
* Replaced boost::shared_ptr with Nektar::ptr
*
* Revision 1.9  2007/07/12 12:52:58  sherwin
* Updated to have a helmholtz matrix
*
* Revision 1.8  2007/07/10 17:17:22  sherwin
* Introduced Scaled Matrices into the MatrixManager
*
* Revision 1.7  2007/05/27 16:10:28  bnelson
* Update to new Array type.
*
* Revision 1.6  2007/04/08 03:33:30  jfrazier
* Minor reformatting and fixing SharedArray usage.
*
* Revision 1.5  2007/04/04 21:49:23  sherwin
* Update for SharedArray
*
* Revision 1.4  2007/03/20 09:13:37  kirby
* new geomfactor routines; update for metricinfo; update style
*
* Revision 1.3  2007/03/09 20:41:50  jfrazier
* *** empty log message ***
*
* Revision 1.2  2007/03/05 08:06:07  sherwin
* Updated to use MemoryManager
*
* Revision 1.1  2007/03/04 20:42:14  sherwin
* Keys for matrix managers
*
***/
<|endoftext|>


<commit_before>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <qt/clientmodel.h>
#include <qt/pairingpage.h>
#include <qt/qrimagewidget.h>

#include <QFormLayout>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>

PairingPage::PairingPage(QWidget *parent) :
    QWidget(parent)
{
    QVBoxLayout *layout = new QVBoxLayout(this);

    QLabel *label_experimental = new QLabel(this);
    label_experimental->setStyleSheet("QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; }");
    label_experimental->setMargin(3);
    label_experimental->setTextInteractionFlags(Qt::TextSelectableByMouse);
    label_experimental->setWordWrap(true);
    label_experimental->setText(tr("Pairing is an experimental feature that currently only works when Tor is enabled. It is expected that the pairing address below will change with future updates, and you may need to re-pair after upgrading."));
    layout->addWidget(label_experimental);

    QLabel *label_summary = new QLabel(this);
    label_summary->setText(tr("Below you will find information to pair other software or devices with this node:"));
    layout->addWidget(label_summary);

    QFormLayout *form_layout = new QFormLayout();
    m_onion_address = new QLineEdit(this);
    m_onion_address->setReadOnly(true);
    form_layout->addRow(tr("Onion address: "), m_onion_address);

    layout->addLayout(form_layout);

    m_qrcode = new QRImageWidget(this);
#ifdef USE_QRCODE
    layout->addWidget(m_qrcode);
#endif

    layout->addStretch();

    refresh();
}

void PairingPage::setClientModel(ClientModel *client_model)
{
    m_client_model = client_model;
    connect(client_model, &ClientModel::networkLocalChanged, this, &PairingPage::refresh);
    refresh();
}

void PairingPage::refresh()
{
    QString onion;
    if (m_client_model && m_client_model->getTorInfo(onion)) {
        m_onion_address->setText(onion);
        m_onion_address->setEnabled(true);
        QString uri = QString("bitcoin-p2p://") + onion;
        m_qrcode->setQR(uri);
        m_qrcode->setVisible(true);
    } else {
        m_onion_address->setText(tr("(not connected)"));
        m_onion_address->setEnabled(false);
        m_qrcode->setVisible(false);
    }
}
<commit_msg>Bugfix: GUI: Pairing: Only attach to non-null client model signals<commit_after>// Copyright (c) 2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#endif

#include <qt/clientmodel.h>
#include <qt/pairingpage.h>
#include <qt/qrimagewidget.h>

#include <QFormLayout>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>

PairingPage::PairingPage(QWidget *parent) :
    QWidget(parent)
{
    QVBoxLayout *layout = new QVBoxLayout(this);

    QLabel *label_experimental = new QLabel(this);
    label_experimental->setStyleSheet("QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop:0 #F0D0A0, stop:1 #F8D488); color:#000000; }");
    label_experimental->setMargin(3);
    label_experimental->setTextInteractionFlags(Qt::TextSelectableByMouse);
    label_experimental->setWordWrap(true);
    label_experimental->setText(tr("Pairing is an experimental feature that currently only works when Tor is enabled. It is expected that the pairing address below will change with future updates, and you may need to re-pair after upgrading."));
    layout->addWidget(label_experimental);

    QLabel *label_summary = new QLabel(this);
    label_summary->setText(tr("Below you will find information to pair other software or devices with this node:"));
    layout->addWidget(label_summary);

    QFormLayout *form_layout = new QFormLayout();
    m_onion_address = new QLineEdit(this);
    m_onion_address->setReadOnly(true);
    form_layout->addRow(tr("Onion address: "), m_onion_address);

    layout->addLayout(form_layout);

    m_qrcode = new QRImageWidget(this);
#ifdef USE_QRCODE
    layout->addWidget(m_qrcode);
#endif

    layout->addStretch();

    refresh();
}

void PairingPage::setClientModel(ClientModel *client_model)
{
    if (m_client_model) {
        disconnect(m_client_model, &ClientModel::networkLocalChanged, this, &PairingPage::refresh);
    }
    m_client_model = client_model;
    if (client_model) {
        connect(client_model, &ClientModel::networkLocalChanged, this, &PairingPage::refresh);
    }
    refresh();
}

void PairingPage::refresh()
{
    QString onion;
    if (m_client_model && m_client_model->getTorInfo(onion)) {
        m_onion_address->setText(onion);
        m_onion_address->setEnabled(true);
        QString uri = QString("bitcoin-p2p://") + onion;
        m_qrcode->setQR(uri);
        m_qrcode->setVisible(true);
    } else {
        m_onion_address->setText(tr("(not connected)"));
        m_onion_address->setEnabled(false);
        m_qrcode->setVisible(false);
    }
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux, Joseph Mirabel
//
// This file is part of hpp-core
// hpp-core 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
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#include <limits>
#include <deque>
#include <cstdlib>
#include <hpp/util/assertion.hh>
#include <hpp/util/debug.hh>
#include <hpp/core/distance.hh>
#include <hpp/core/path-validation.hh>
#include <hpp/core/path-vector.hh>
#include <hpp/core/problem.hh>
#include <hpp/core/random-shortcut.hh>
#include <hpp/core/path-projector.hh>

namespace hpp {
  namespace core {
    // Compute the length of a vector of paths assuming that each element
    // is optimal for the given distance.
    template <bool reEstimateLength = false> struct PathLength {
      static inline value_type run (const PathVectorPtr_t& path,
                             const DistancePtr_t& distance)
      {
        if (reEstimateLength) return path->length ();
        else {
          value_type result = 0;
          for (std::size_t i=0; i<path->numberPaths (); ++i) {
            const PathPtr_t& element (path->pathAtRank (i));
            Configuration_t q1 = element->initial ();
            Configuration_t q2 = element->end ();
            result += (*distance) (q1, q2);
          }
          return result;
        }
      }
    };

    RandomShortcutPtr_t
    RandomShortcut::create (const Problem& problem)
    {
      RandomShortcut* ptr = new RandomShortcut (problem);
      return RandomShortcutPtr_t (ptr);
    }

    RandomShortcut::RandomShortcut (const Problem& problem) :
      PathOptimizer (problem)
    {
    }

    PathVectorPtr_t RandomShortcut::optimize (const PathVectorPtr_t& path)
    {
      using std::numeric_limits;
      using std::make_pair;
      bool finished = false;
      value_type t[4];
      Configuration_t q[4];
      q[0] = path->initial();
      q[1].resize(path->outputSize ()),
      q[2].resize(path->outputSize ());
      q[3] = path->end();
      PathVectorPtr_t tmpPath = path;

      // Maximal number of iterations without improvements
      const std::size_t n = problem().getParameter("PathOptimization/NumberOfLoops").intValue();
      std::size_t projectionError = n;
      std::deque <value_type> length (n-1,
				      numeric_limits <value_type>::infinity ());
      length.push_back (PathLength<>::run (tmpPath, problem ().distance ()));
      PathVectorPtr_t result;

      while (!finished && projectionError != 0) {
        t[0] = tmpPath->timeRange ().first;
        t[3] = tmpPath->timeRange ().second;
	value_type u2 = (t[3]-t[0]) * rand ()/RAND_MAX;
	value_type u1 = (t[3]-t[0]) * rand ()/RAND_MAX;
	if (u1 < u2) {
          t[1] = t[0] + u1; t[2] = t[0] + u2;
        } else {
          t[1] = t[0] + u2; t[2] = t[0] + u1;
        }
        bool error = false;
        for (int i = 1; i < 3; ++i) {
          if (!(*tmpPath) (q[i], t[i])) {
            hppDout (error, "Configuration at param "
                << t[i] << " could not be projected");
            projectionError--;
            error = true;
            break;
          }
        }
        if (error) continue;
	// Validate sub parts
	bool valid [3];
	PathPtr_t proj [3];
        // Build and projects the path
        for (int i = 0; i < 3; ++i)
          proj[i] = steer (q[i], q[i+1]);
        if (!proj[0] && !proj[1] && !proj[2]) {
          hppDout (info, "Enable to create a valid path");
          projectionError--;
          continue;
        }
        // validate the paths
        for (unsigned i=0; i<3; ++i) {
	  PathPtr_t validPart;
	  PathValidationReportPtr_t report;
          if (!proj [i]) valid[i] = false;
          else
            valid [i] = problem ().pathValidation ()->validate
              (proj [i], false, validPart, report);
	}
	// Replace valid parts
	result = PathVector::create (path->outputSize (),
				     path->outputDerivativeSize ());
        try {
          for (int i = 0; i < 3; ++i) {
            if (valid [i])
              result->appendPath (proj [i]);
            else
              result->concatenate (tmpPath->extract
                                   (make_pair (t[i], t[i+1]))->
                                   as <PathVector> ());
          }
        } catch (const projection_error& e) {
          hppDout (error, "Caught exception at with time " << t[1] << " and " <<
              t[2] << ": " << e.what ());
          projectionError--;
          result = tmpPath;
          continue;
        }
        value_type newLength = PathLength<>::run (result, problem ().distance ());
        if (length[n-1] <= newLength) {
          hppDout (info,  "the length would increase:" << length[n-1] << " " << newLength);
          result = tmpPath;
          projectionError--;
        } else {
          length.push_back (newLength);
          length.pop_front ();
          finished = (length [0] - length [n-1]) <= 1e-4 * length[n-1];
          hppDout (info, "length = " << length [n-1]);
          tmpPath = result;
          projectionError = n;
        }
      }
      if (!result) return path;
      hppDout (info, "RandomShortcut:" << *result);
      for (std::size_t i = 0; i < result->numberPaths (); ++i) {
        if (result->pathAtRank(i)->constraints())
          hppDout (info, "At rank " << i << ", constraints are " <<
              *result->pathAtRank(i)->constraints());
        else
          hppDout (info, "At rank " << i << ", no constraints");
      }
      return result;
    }

    // ----------- Declare parameters ------------------------------------- //

    HPP_START_PARAMETER_DECLARATION(RandomShortcut)
    Problem::declareParameter(ParameterDescription (Parameter::INT,
          "RandomShortcut/NumberOfLoops",
          "Number of loops.",
          Parameter((size_type)5)));
    HPP_END_PARAMETER_DECLARATION(RandomShortcut)
  } // namespace core
} // namespace hpp
<commit_msg>Fix parameter PathOptimization/RandomShortcut/NumberOfLoops<commit_after>//
// Copyright (c) 2014 CNRS
// Authors: Florent Lamiraux, Joseph Mirabel
//
// This file is part of hpp-core
// hpp-core 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
// 3 of the License, or (at your option) any later version.
//
// hpp-core is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Lesser Public License for more details.  You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-core  If not, see
// <http://www.gnu.org/licenses/>.

#include <limits>
#include <deque>
#include <cstdlib>
#include <hpp/util/assertion.hh>
#include <hpp/util/debug.hh>
#include <hpp/core/distance.hh>
#include <hpp/core/path-validation.hh>
#include <hpp/core/path-vector.hh>
#include <hpp/core/problem.hh>
#include <hpp/core/random-shortcut.hh>
#include <hpp/core/path-projector.hh>

namespace hpp {
  namespace core {
    // Compute the length of a vector of paths assuming that each element
    // is optimal for the given distance.
    template <bool reEstimateLength = false> struct PathLength {
      static inline value_type run (const PathVectorPtr_t& path,
                             const DistancePtr_t& distance)
      {
        if (reEstimateLength) return path->length ();
        else {
          value_type result = 0;
          for (std::size_t i=0; i<path->numberPaths (); ++i) {
            const PathPtr_t& element (path->pathAtRank (i));
            Configuration_t q1 = element->initial ();
            Configuration_t q2 = element->end ();
            result += (*distance) (q1, q2);
          }
          return result;
        }
      }
    };

    RandomShortcutPtr_t
    RandomShortcut::create (const Problem& problem)
    {
      RandomShortcut* ptr = new RandomShortcut (problem);
      return RandomShortcutPtr_t (ptr);
    }

    RandomShortcut::RandomShortcut (const Problem& problem) :
      PathOptimizer (problem)
    {
    }

    PathVectorPtr_t RandomShortcut::optimize (const PathVectorPtr_t& path)
    {
      using std::numeric_limits;
      using std::make_pair;
      bool finished = false;
      value_type t[4];
      Configuration_t q[4];
      q[0] = path->initial();
      q[1].resize(path->outputSize ()),
      q[2].resize(path->outputSize ());
      q[3] = path->end();
      PathVectorPtr_t tmpPath = path;

      // Maximal number of iterations without improvements
      const std::size_t n = problem().getParameter("PathOptimization/RandomShortcut/NumberOfLoops").intValue();
      std::size_t projectionError = n;
      std::deque <value_type> length (n-1,
				      numeric_limits <value_type>::infinity ());
      length.push_back (PathLength<>::run (tmpPath, problem ().distance ()));
      PathVectorPtr_t result;

      while (!finished && projectionError != 0) {
        t[0] = tmpPath->timeRange ().first;
        t[3] = tmpPath->timeRange ().second;
	value_type u2 = (t[3]-t[0]) * rand ()/RAND_MAX;
	value_type u1 = (t[3]-t[0]) * rand ()/RAND_MAX;
	if (u1 < u2) {
          t[1] = t[0] + u1; t[2] = t[0] + u2;
        } else {
          t[1] = t[0] + u2; t[2] = t[0] + u1;
        }
        bool error = false;
        for (int i = 1; i < 3; ++i) {
          if (!(*tmpPath) (q[i], t[i])) {
            hppDout (error, "Configuration at param "
                << t[i] << " could not be projected");
            projectionError--;
            error = true;
            break;
          }
        }
        if (error) continue;
	// Validate sub parts
	bool valid [3];
	PathPtr_t proj [3];
        // Build and projects the path
        for (int i = 0; i < 3; ++i)
          proj[i] = steer (q[i], q[i+1]);
        if (!proj[0] && !proj[1] && !proj[2]) {
          hppDout (info, "Enable to create a valid path");
          projectionError--;
          continue;
        }
        // validate the paths
        for (unsigned i=0; i<3; ++i) {
	  PathPtr_t validPart;
	  PathValidationReportPtr_t report;
          if (!proj [i]) valid[i] = false;
          else
            valid [i] = problem ().pathValidation ()->validate
              (proj [i], false, validPart, report);
	}
	// Replace valid parts
	result = PathVector::create (path->outputSize (),
				     path->outputDerivativeSize ());
        try {
          for (int i = 0; i < 3; ++i) {
            if (valid [i])
              result->appendPath (proj [i]);
            else
              result->concatenate (tmpPath->extract
                                   (make_pair (t[i], t[i+1]))->
                                   as <PathVector> ());
          }
        } catch (const projection_error& e) {
          hppDout (error, "Caught exception at with time " << t[1] << " and " <<
              t[2] << ": " << e.what ());
          projectionError--;
          result = tmpPath;
          continue;
        }
        value_type newLength = PathLength<>::run (result, problem ().distance ());
        if (length[n-1] <= newLength) {
          hppDout (info,  "the length would increase:" << length[n-1] << " " << newLength);
          result = tmpPath;
          projectionError--;
        } else {
          length.push_back (newLength);
          length.pop_front ();
          finished = (length [0] - length [n-1]) <= 1e-4 * length[n-1];
          hppDout (info, "length = " << length [n-1]);
          tmpPath = result;
          projectionError = n;
        }
      }
      if (!result) return path;
      hppDout (info, "RandomShortcut:" << *result);
      for (std::size_t i = 0; i < result->numberPaths (); ++i) {
        if (result->pathAtRank(i)->constraints())
          hppDout (info, "At rank " << i << ", constraints are " <<
              *result->pathAtRank(i)->constraints());
        else
          hppDout (info, "At rank " << i << ", no constraints");
      }
      return result;
    }

    // ----------- Declare parameters ------------------------------------- //

    HPP_START_PARAMETER_DECLARATION(RandomShortcut)
    Problem::declareParameter(ParameterDescription (Parameter::INT,
          "PathOptimization/RandomShortcut/NumberOfLoops",
          "Number of loops.",
          Parameter((size_type)5)));
    HPP_END_PARAMETER_DECLARATION(RandomShortcut)
  } // namespace core
} // namespace hpp
<|endoftext|>


<commit_before>/*
    Copyright (c) 2009-2011 250bpm s.r.o.
    Copyright (c) 2011 Botond Ballo
    Copyright (c) 2007-2009 iMatix Corporation

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to
    deal in the Software without restriction, including without limitation the
    rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    sell copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    IN THE SOFTWARE.
*/

#ifndef __ZMQ_HPP_INCLUDED__
#define __ZMQ_HPP_INCLUDED__

#include <zmq.h>

#include <cassert>
#include <cstring>
#include <algorithm>
#include <exception>

//  Detect whether the compiler supports C++11 rvalue references.
#if (defined(__GNUC__) && (__GNUC__ > 4 || \
      (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && \
      defined(__GXX_EXPERIMENTAL_CXX0X__))
    #define ZMQ_HAS_RVALUE_REFS
#endif
#if (defined(__clang__))
    #if __has_feature(cxx_rvalue_references)
        #define ZMQ_HAS_RVALUE_REFS
    #endif
#endif
#if (defined(_MSC_VER) && (_MSC_VER >= 1600))
    #define ZMQ_HAS_RVALUE_REFS
#endif

// In order to prevent unused variable warnings when building in non-debug
// mode use this macro to make assertions.
#ifndef NDEBUG
#   define ZMQ_ASSERT(expression) assert(expression)
#else
#   define ZMQ_ASSERT(expression) (expression)
#endif

namespace zmq
{

    typedef zmq_free_fn free_fn;
    typedef zmq_pollitem_t pollitem_t;

    class error_t : public std::exception
    {
    public:

        error_t () : errnum (zmq_errno ()) {}

        virtual const char *what () const throw ()
        {
            return zmq_strerror (errnum);
        }

        int num () const
        {
            return errnum;
        }

    private:

        int errnum;
    };

    inline int poll (zmq_pollitem_t *items_, int nitems_, long timeout_ = -1)
    {
        int rc = zmq_poll (items_, nitems_, timeout_);
        if (rc < 0)
            throw error_t ();
        return rc;
    }

    inline void version (int *major_, int *minor_, int *patch_)
    {
        zmq_version (major_, minor_, patch_);
    }

    class message_t
    {
        friend class socket_t;

    public:

        inline message_t ()
        {
            int rc = zmq_msg_init (&msg);
            if (rc != 0)
                throw error_t ();
        }

        inline message_t (size_t size_)
        {
            int rc = zmq_msg_init_size (&msg, size_);
            if (rc != 0)
                throw error_t ();
        }

        inline message_t (void *data_, size_t size_, free_fn *ffn_,
            void *hint_ = NULL)
        {
            int rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_);
            if (rc != 0)
                throw error_t ();
        }

        inline ~message_t ()
        {
            int rc = zmq_msg_close (&msg);
            ZMQ_ASSERT (rc == 0);
        }

        inline void rebuild ()
        {
            int rc = zmq_msg_close (&msg);
            if (rc != 0)
                throw error_t ();
            rc = zmq_msg_init (&msg);
            if (rc != 0)
                throw error_t ();
        }

        inline void rebuild (size_t size_)
        {
            int rc = zmq_msg_close (&msg);
            if (rc != 0)
                throw error_t ();
            rc = zmq_msg_init_size (&msg, size_);
            if (rc != 0)
                throw error_t ();
        }

        inline void rebuild (void *data_, size_t size_, free_fn *ffn_,
            void *hint_ = NULL)
        {
            int rc = zmq_msg_close (&msg);
            if (rc != 0)
                throw error_t ();
            rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_);
            if (rc != 0)
                throw error_t ();
        }

        inline void move (message_t *msg_)
        {
            int rc = zmq_msg_move (&msg, &(msg_->msg));
            if (rc != 0)
                throw error_t ();
        }

        inline void copy (message_t *msg_)
        {
            int rc = zmq_msg_copy (&msg, &(msg_->msg));
            if (rc != 0)
                throw error_t ();
        }

        inline void *data ()
        {
            return zmq_msg_data (&msg);
        }

        inline size_t size ()
        {
            return zmq_msg_size (&msg);
        }

    private:

        //  The underlying message
        zmq_msg_t msg;

        //  Disable implicit message copying, so that users won't use shared
        //  messages (less efficient) without being aware of the fact.
        message_t (const message_t&);
        void operator = (const message_t&);
    };

    class context_t
    {
        friend class socket_t;

    public:

        inline context_t (int io_threads_)
        {
            ptr = zmq_init (io_threads_);
            if (ptr == NULL)
                throw error_t ();
        }

#ifdef ZMQ_HAS_RVALUE_REFS
        inline context_t (context_t &&rhs) : ptr (rhs.ptr)
        {
            rhs.ptr = NULL;
        }
        inline context_t &operator = (context_t &&rhs)
        {
            std::swap (ptr, rhs.ptr);
            return *this;
        }
#endif

        inline ~context_t ()
        {
            if (ptr == NULL)
                return;
            int rc = zmq_term (ptr);
            ZMQ_ASSERT (rc == 0);
        }

        //  Be careful with this, it's probably only useful for
        //  using the C api together with an existing C++ api.
        //  Normally you should never need to use this.
        inline operator void* ()
        {
            return ptr;
        }

    private:

        void *ptr;

        context_t (const context_t&);
        void operator = (const context_t&);
    };

    class socket_t
    {
    public:

        inline socket_t (context_t &context_, int type_)
        {
            ptr = zmq_socket (context_.ptr, type_);
            if (ptr == NULL)
                throw error_t ();
        }

#ifdef ZMQ_HAS_RVALUE_REFS
        inline socket_t(socket_t&& rhs) : ptr(rhs.ptr)
        {
            rhs.ptr = NULL;
        }
        inline socket_t& operator=(socket_t&& rhs)
        {
            std::swap(ptr, rhs.ptr);
            return *this;
        }
#endif

        inline ~socket_t ()
        {
            close();
        }

        inline operator void* ()
        {
            return ptr;
        }

        inline void close()
        {
            if(ptr == NULL)
                // already closed
                return ;
            int rc = zmq_close (ptr);
            ZMQ_ASSERT (rc == 0);
            ptr = 0 ;
        }

        inline void setsockopt (int option_, const void *optval_,
            size_t optvallen_)
        {
            int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_);
            if (rc != 0)
                throw error_t ();
        }

        inline void getsockopt (int option_, void *optval_,
            size_t *optvallen_)
        {
            int rc = zmq_getsockopt (ptr, option_, optval_, optvallen_);
            if (rc != 0)
                throw error_t ();
        }

        inline void bind (const char *addr_)
        {
            int rc = zmq_bind (ptr, addr_);
            if (rc != 0)
                throw error_t ();
        }

        inline void connect (const char *addr_)
        {
            int rc = zmq_connect (ptr, addr_);
            if (rc != 0)
                throw error_t ();
        }

        inline size_t send (const void *buf_, size_t len_, int flags_ = 0)
        {
            int nbytes = zmq_send (ptr, buf_, len_, flags_);
            if (nbytes >= 0)
                return (size_t) nbytes;
            if (zmq_errno () == EAGAIN)
                return 0;
            throw error_t ();
        }

        inline bool send (message_t &msg_, int flags_ = 0)
        {
            int nbytes = zmq_sendmsg (ptr, &(msg_.msg), flags_);
            if (nbytes >= 0)
                return true;
            if (zmq_errno () == EAGAIN)
                return false;
            throw error_t ();
        }

        inline size_t recv (void *buf_, size_t len_, int flags_ = 0)
        {
            int nbytes = zmq_recv (ptr, buf_, len_, flags_);
            if (nbytes >= 0)
                return (size_t) nbytes;
            if (zmq_errno () == EAGAIN)
                return 0;
            throw error_t ();
        }

        inline bool recv (message_t *msg_, int flags_ = 0)
        {
            int nbytes = zmq_recvmsg (ptr, &(msg_->msg), flags_);
            if (nbytes >= 0)
                return true;
            if (zmq_errno () == EAGAIN)
                return false;
            throw error_t ();
        }

    private:

        void *ptr;

        socket_t (const socket_t&);
        void operator = (const socket_t&);
    };

}

#endif

<commit_msg>Added 'connected' method to socket_t class.<commit_after>/*
    Copyright (c) 2009-2011 250bpm s.r.o.
    Copyright (c) 2011 Botond Ballo
    Copyright (c) 2007-2009 iMatix Corporation

    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to
    deal in the Software without restriction, including without limitation the
    rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
    sell copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    IN THE SOFTWARE.
*/

#ifndef __ZMQ_HPP_INCLUDED__
#define __ZMQ_HPP_INCLUDED__

#include <zmq.h>

#include <cassert>
#include <cstring>
#include <algorithm>
#include <exception>

//  Detect whether the compiler supports C++11 rvalue references.
#if (defined(__GNUC__) && (__GNUC__ > 4 || \
      (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) && \
      defined(__GXX_EXPERIMENTAL_CXX0X__))
    #define ZMQ_HAS_RVALUE_REFS
#endif
#if (defined(__clang__))
    #if __has_feature(cxx_rvalue_references)
        #define ZMQ_HAS_RVALUE_REFS
    #endif
#endif
#if (defined(_MSC_VER) && (_MSC_VER >= 1600))
    #define ZMQ_HAS_RVALUE_REFS
#endif

// In order to prevent unused variable warnings when building in non-debug
// mode use this macro to make assertions.
#ifndef NDEBUG
#   define ZMQ_ASSERT(expression) assert(expression)
#else
#   define ZMQ_ASSERT(expression) (expression)
#endif

namespace zmq
{

    typedef zmq_free_fn free_fn;
    typedef zmq_pollitem_t pollitem_t;

    class error_t : public std::exception
    {
    public:

        error_t () : errnum (zmq_errno ()) {}

        virtual const char *what () const throw ()
        {
            return zmq_strerror (errnum);
        }

        int num () const
        {
            return errnum;
        }

    private:

        int errnum;
    };

    inline int poll (zmq_pollitem_t *items_, int nitems_, long timeout_ = -1)
    {
        int rc = zmq_poll (items_, nitems_, timeout_);
        if (rc < 0)
            throw error_t ();
        return rc;
    }

    inline void version (int *major_, int *minor_, int *patch_)
    {
        zmq_version (major_, minor_, patch_);
    }

    class message_t
    {
        friend class socket_t;

    public:

        inline message_t ()
        {
            int rc = zmq_msg_init (&msg);
            if (rc != 0)
                throw error_t ();
        }

        inline message_t (size_t size_)
        {
            int rc = zmq_msg_init_size (&msg, size_);
            if (rc != 0)
                throw error_t ();
        }

        inline message_t (void *data_, size_t size_, free_fn *ffn_,
            void *hint_ = NULL)
        {
            int rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_);
            if (rc != 0)
                throw error_t ();
        }

        inline ~message_t ()
        {
            int rc = zmq_msg_close (&msg);
            ZMQ_ASSERT (rc == 0);
        }

        inline void rebuild ()
        {
            int rc = zmq_msg_close (&msg);
            if (rc != 0)
                throw error_t ();
            rc = zmq_msg_init (&msg);
            if (rc != 0)
                throw error_t ();
        }

        inline void rebuild (size_t size_)
        {
            int rc = zmq_msg_close (&msg);
            if (rc != 0)
                throw error_t ();
            rc = zmq_msg_init_size (&msg, size_);
            if (rc != 0)
                throw error_t ();
        }

        inline void rebuild (void *data_, size_t size_, free_fn *ffn_,
            void *hint_ = NULL)
        {
            int rc = zmq_msg_close (&msg);
            if (rc != 0)
                throw error_t ();
            rc = zmq_msg_init_data (&msg, data_, size_, ffn_, hint_);
            if (rc != 0)
                throw error_t ();
        }

        inline void move (message_t *msg_)
        {
            int rc = zmq_msg_move (&msg, &(msg_->msg));
            if (rc != 0)
                throw error_t ();
        }

        inline void copy (message_t *msg_)
        {
            int rc = zmq_msg_copy (&msg, &(msg_->msg));
            if (rc != 0)
                throw error_t ();
        }

        inline void *data ()
        {
            return zmq_msg_data (&msg);
        }

        inline size_t size ()
        {
            return zmq_msg_size (&msg);
        }

    private:

        //  The underlying message
        zmq_msg_t msg;

        //  Disable implicit message copying, so that users won't use shared
        //  messages (less efficient) without being aware of the fact.
        message_t (const message_t&);
        void operator = (const message_t&);
    };

    class context_t
    {
        friend class socket_t;

    public:

        inline context_t (int io_threads_)
        {
            ptr = zmq_init (io_threads_);
            if (ptr == NULL)
                throw error_t ();
        }

#ifdef ZMQ_HAS_RVALUE_REFS
        inline context_t (context_t &&rhs) : ptr (rhs.ptr)
        {
            rhs.ptr = NULL;
        }
        inline context_t &operator = (context_t &&rhs)
        {
            std::swap (ptr, rhs.ptr);
            return *this;
        }
#endif

        inline ~context_t ()
        {
            if (ptr == NULL)
                return;
            int rc = zmq_term (ptr);
            ZMQ_ASSERT (rc == 0);
        }

        //  Be careful with this, it's probably only useful for
        //  using the C api together with an existing C++ api.
        //  Normally you should never need to use this.
        inline operator void* ()
        {
            return ptr;
        }

    private:

        void *ptr;

        context_t (const context_t&);
        void operator = (const context_t&);
    };

    class socket_t
    {
    public:

        inline socket_t (context_t &context_, int type_)
        {
            ptr = zmq_socket (context_.ptr, type_);
            if (ptr == NULL)
                throw error_t ();
        }

#ifdef ZMQ_HAS_RVALUE_REFS
        inline socket_t(socket_t&& rhs) : ptr(rhs.ptr)
        {
            rhs.ptr = NULL;
        }
        inline socket_t& operator=(socket_t&& rhs)
        {
            std::swap(ptr, rhs.ptr);
            return *this;
        }
#endif

        inline ~socket_t ()
        {
            close();
        }

        inline operator void* ()
        {
            return ptr;
        }

        inline void close()
        {
            if(ptr == NULL)
                // already closed
                return ;
            int rc = zmq_close (ptr);
            ZMQ_ASSERT (rc == 0);
            ptr = 0 ;
        }

        inline void setsockopt (int option_, const void *optval_,
            size_t optvallen_)
        {
            int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_);
            if (rc != 0)
                throw error_t ();
        }

        inline void getsockopt (int option_, void *optval_,
            size_t *optvallen_)
        {
            int rc = zmq_getsockopt (ptr, option_, optval_, optvallen_);
            if (rc != 0)
                throw error_t ();
        }

        inline void bind (const char *addr_)
        {
            int rc = zmq_bind (ptr, addr_);
            if (rc != 0)
                throw error_t ();
        }

        inline void connect (const char *addr_)
        {
            int rc = zmq_connect (ptr, addr_);
            if (rc != 0)
                throw error_t ();
        }

        inline bool connected()
        {
            return(ptr != NULL);
        }

        inline size_t send (const void *buf_, size_t len_, int flags_ = 0)
        {
            int nbytes = zmq_send (ptr, buf_, len_, flags_);
            if (nbytes >= 0)
                return (size_t) nbytes;
            if (zmq_errno () == EAGAIN)
                return 0;
            throw error_t ();
        }

        inline bool send (message_t &msg_, int flags_ = 0)
        {
            int nbytes = zmq_sendmsg (ptr, &(msg_.msg), flags_);
            if (nbytes >= 0)
                return true;
            if (zmq_errno () == EAGAIN)
                return false;
            throw error_t ();
        }

        inline size_t recv (void *buf_, size_t len_, int flags_ = 0)
        {
            int nbytes = zmq_recv (ptr, buf_, len_, flags_);
            if (nbytes >= 0)
                return (size_t) nbytes;
            if (zmq_errno () == EAGAIN)
                return 0;
            throw error_t ();
        }

        inline bool recv (message_t *msg_, int flags_ = 0)
        {
            int nbytes = zmq_recvmsg (ptr, &(msg_->msg), flags_);
            if (nbytes >= 0)
                return true;
            if (zmq_errno () == EAGAIN)
                return false;
            throw error_t ();
        }

    private:

        void *ptr;

        socket_t (const socket_t&);
        void operator = (const socket_t&);
    };

}

#endif

<|endoftext|>


<commit_before>/* examples/poweroftwo_ranks.C
 *
 * Copyright (C) 2012 LinBox
 * Written by J-G Dumas
 * Time-stamp: <06 Apr 12 11:08:48 Jean-Guillaume.Dumas@imag.fr>
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox 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
 * ========LICENCE========
 */

/** \file examples/poweroftwo_ranks.C
 * @example  examples/poweroftwo_ranks.C
  \brief Ranks of sparse matrix modulo 2^k
  \ingroup examples
  */
#include <linbox/linbox-config.h>

#include <iostream>

#include <linbox/field/givaro.h>
#include <linbox/matrix/sparse-matrix.h>
#include <linbox/algorithms/smith-form-sparseelim-poweroftwo.h>

using namespace LinBox;
using namespace std;

int main (int argc, char **argv) {
    commentator().setMaxDetailLevel (-1);
    commentator().setMaxDepth (-1);
    commentator().setReportStream (std::cerr);

    if (argc < 3 || argc > 3)
    {	cerr << "Usage: rank <matrix-file-in-supported-format> <power of two exponent>]" << endl; return -1; }

    ifstream input (argv[1]);
    if (!input) { cerr << "Error opening matrix file: " << argv[1] << endl; return -1; }

    // long unsigned int r;

    if (argc == 3) {
        LinBox::Timer tim;
        size_t exponent = atoi(argv[2]);
        if (exponent > 63) {
            typedef std::vector<std::pair<size_t,Integer> >  Smith_t;
            typedef LinBox::PID_integer Ring;
            Ring ZZ;
            Smith_t local;
            LinBox::MatrixStream<Ring> ms( ZZ, input );
            LinBox::SparseMatrix<Ring, LinBox::SparseMatrixFormat::SparseSeq > A (ms);
            input.close();
            LinBox::PowerGaussDomainPowerOfTwo< Givaro::Integer > PGD;
            tim.clear(); tim.start();
            PGD(local, A, exponent);
            tim.stop();

            std::cout << "Local Smith Form : (";
            for (Smith_t::const_iterator  p = local.begin(); p != local.end(); ++p)
                std::cout << '[' << p->second << ',' << p->first << "] ";
            cout << ')' << endl;
        } else {
            typedef std::vector<std::pair<size_t,uint64_t> > Smith_t;
            typedef LinBox::UnparametricField<int64_t> Ring;
            Smith_t local;
            Ring R;
            LinBox::MatrixStream<Ring> ms( R, input );
            LinBox::SparseMatrix<Ring, LinBox::SparseMatrixFormat::SparseSeq > A (ms);
            input.close();
            LinBox::PowerGaussDomainPowerOfTwo< uint64_t > PGD;

            tim.clear(); tim.start();
            PGD(local, A, exponent);
            tim.stop();

            std::cout << "Local Smith Form : (";
            for (Smith_t::const_iterator  p = local.begin(); p != local.end(); ++p)
                std::cout << '[' << p->second << ',' << p->first << "] ";
            cout << ')' << endl;
        }

        std::cerr << tim << std::endl;
    }

    return 0;
}

// Local Variables:
// mode: C++
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 8
// End:
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<commit_msg>output<commit_after>/* examples/poweroftwo_ranks.C
 *
 * Copyright (C) 2012 LinBox
 * Written by J-G Dumas
 * Time-stamp: <13 Mar 14 14:14:09 Jean-Guillaume.Dumas@imag.fr>
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox 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
 * ========LICENCE========
 */

/** \file examples/poweroftwo_ranks.C
 * @example  examples/poweroftwo_ranks.C
  \brief Ranks of sparse matrix modulo 2^k
  \ingroup examples
  */
#include <linbox/linbox-config.h>

#include <iostream>

#include <linbox/field/givaro.h>
#include <linbox/matrix/sparse-matrix.h>
#include <linbox/algorithms/smith-form-sparseelim-poweroftwo.h>

using namespace LinBox;
using namespace std;

int main (int argc, char **argv) {
    commentator().setMaxDetailLevel (-1);
    commentator().setMaxDepth (-1);
    commentator().setReportStream (std::cerr);

    if (argc < 3 || argc > 3)
    {	cerr << "Usage: rank <matrix-file-in-supported-format> <power of two exponent>]" << endl; return -1; }

    ifstream input (argv[1]);
    if (!input) { cerr << "Error opening matrix file: " << argv[1] << endl; return -1; }

    // long unsigned int r;

    if (argc == 3) {
        LinBox::Timer tim;
        size_t exponent = atoi(argv[2]);
        if (exponent > 63) {
            typedef std::vector<std::pair<size_t,Integer> >  Smith_t;
            typedef LinBox::PID_integer Ring;
            Ring ZZ;
            Smith_t local;
            LinBox::MatrixStream<Ring> ms( ZZ, input );
            LinBox::SparseMatrix<Ring, LinBox::SparseMatrixFormat::SparseSeq > A (ms);
            input.close();
            LinBox::PowerGaussDomainPowerOfTwo< Givaro::Integer > PGD;
            tim.clear(); tim.start();
            PGD(local, A, exponent);
            tim.stop();

            ZZ.write(std::cout << "Local Smith Form ") << " : " << std::endl << '(';
            for (Smith_t::const_iterator  p = local.begin(); p != local.end(); ++p)
                std::cout << '[' << p->second << ',' << p->first << "] ";
            cout << ')' << endl;
        } else {
            typedef std::vector<std::pair<size_t,uint64_t> > Smith_t;
            typedef LinBox::UnparametricField<int64_t> Ring;
            Smith_t local;
            Ring R;
            LinBox::MatrixStream<Ring> ms( R, input );
            LinBox::SparseMatrix<Ring, LinBox::SparseMatrixFormat::SparseSeq > A (ms);
            input.close();
            LinBox::PowerGaussDomainPowerOfTwo< uint64_t > PGD;

            tim.clear(); tim.start();
            PGD(local, A, exponent);
            tim.stop();

            R.write(std::cout << "Local Smith Form ") << " : " << std::endl << '(';
            for (Smith_t::const_iterator  p = local.begin(); p != local.end(); ++p)
                std::cout << '[' << p->second << ',' << p->first << "] ";
            cout << ')' << endl;
        }

        std::cerr << tim << std::endl;
    }

    return 0;
}

// Local Variables:
// mode: C++
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 8
// End:
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <validationinterface.h>

#include <primitives/block.h>
#include <scheduler.h>
#include <txmempool.h>
#include <util/system.h>
#include <validation.h>

#include <list>
#include <atomic>
#include <future>
#include <utility>

#include <boost/signals2/signal.hpp>

struct ValidationInterfaceConnections {
    boost::signals2::scoped_connection UpdatedBlockTip;
    boost::signals2::scoped_connection TransactionAddedToMempool;
    boost::signals2::scoped_connection BlockConnected;
    boost::signals2::scoped_connection BlockDisconnected;
    boost::signals2::scoped_connection TransactionRemovedFromMempool;
    boost::signals2::scoped_connection ChainStateFlushed;
    boost::signals2::scoped_connection Broadcast;
    boost::signals2::scoped_connection BlockChecked;
    boost::signals2::scoped_connection NewPoWValidBlock;
};

struct MainSignalsInstance {
    boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip;
    boost::signals2::signal<void (const CTransactionRef &)> TransactionAddedToMempool;
    boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef>&)> BlockConnected;
    boost::signals2::signal<void (const std::shared_ptr<const CBlock> &)> BlockDisconnected;
    boost::signals2::signal<void (const CTransactionRef &)> TransactionRemovedFromMempool;
    boost::signals2::signal<void (const CBlockLocator &)> ChainStateFlushed;
    boost::signals2::signal<void (int64_t nBestBlockTime, CConnman* connman)> Broadcast;
    boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
    boost::signals2::signal<void (const CBlockIndex *, const std::shared_ptr<const CBlock>&)> NewPoWValidBlock;

    // We are not allowed to assume the scheduler only runs in one thread,
    // but must ensure all callbacks happen in-order, so we end up creating
    // our own queue here :(
    SingleThreadedSchedulerClient m_schedulerClient;
    std::unordered_map<CValidationInterface*, ValidationInterfaceConnections> m_connMainSignals;

    explicit MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {}
};

static CMainSignals g_signals;

// This map has to a separate global instead of a member of MainSignalsInstance,
// because RegisterWithMempoolSignals is currently called before RegisterBackgroundSignalScheduler,
// so MainSignalsInstance hasn't been created yet.
static std::unordered_map<CTxMemPool*, boost::signals2::scoped_connection> g_connNotifyEntryRemoved;

void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler) {
    assert(!m_internals);
    m_internals.reset(new MainSignalsInstance(&scheduler));
}

void CMainSignals::UnregisterBackgroundSignalScheduler() {
    m_internals.reset(nullptr);
}

void CMainSignals::FlushBackgroundCallbacks() {
    if (m_internals) {
        m_internals->m_schedulerClient.EmptyQueue();
    }
}

size_t CMainSignals::CallbacksPending() {
    if (!m_internals) return 0;
    return m_internals->m_schedulerClient.CallbacksPending();
}

void CMainSignals::RegisterWithMempoolSignals(CTxMemPool& pool) {
    g_connNotifyEntryRemoved.emplace(std::piecewise_construct,
        std::forward_as_tuple(&pool),
        std::forward_as_tuple(pool.NotifyEntryRemoved.connect(std::bind(&CMainSignals::MempoolEntryRemoved, this, std::placeholders::_1, std::placeholders::_2)))
    );
}

void CMainSignals::UnregisterWithMempoolSignals(CTxMemPool& pool) {
    g_connNotifyEntryRemoved.erase(&pool);
}

CMainSignals& GetMainSignals()
{
    return g_signals;
}

void RegisterValidationInterface(CValidationInterface* pwalletIn) {
    ValidationInterfaceConnections& conns = g_signals.m_internals->m_connMainSignals[pwalletIn];
    conns.UpdatedBlockTip = g_signals.m_internals->UpdatedBlockTip.connect(std::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    conns.TransactionAddedToMempool = g_signals.m_internals->TransactionAddedToMempool.connect(std::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, std::placeholders::_1));
    conns.BlockConnected = g_signals.m_internals->BlockConnected.connect(std::bind(&CValidationInterface::BlockConnected, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    conns.BlockDisconnected = g_signals.m_internals->BlockDisconnected.connect(std::bind(&CValidationInterface::BlockDisconnected, pwalletIn, std::placeholders::_1));
    conns.TransactionRemovedFromMempool = g_signals.m_internals->TransactionRemovedFromMempool.connect(std::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, std::placeholders::_1));
    conns.ChainStateFlushed = g_signals.m_internals->ChainStateFlushed.connect(std::bind(&CValidationInterface::ChainStateFlushed, pwalletIn, std::placeholders::_1));
    conns.Broadcast = g_signals.m_internals->Broadcast.connect(std::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, std::placeholders::_1, std::placeholders::_2));
    conns.BlockChecked = g_signals.m_internals->BlockChecked.connect(std::bind(&CValidationInterface::BlockChecked, pwalletIn, std::placeholders::_1, std::placeholders::_2));
    conns.NewPoWValidBlock = g_signals.m_internals->NewPoWValidBlock.connect(std::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, std::placeholders::_1, std::placeholders::_2));
}

void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
    g_signals.m_internals->m_connMainSignals.erase(pwalletIn);
}

void UnregisterAllValidationInterfaces() {
    if (!g_signals.m_internals) {
        return;
    }
    g_signals.m_internals->m_connMainSignals.clear();
}

void CallFunctionInValidationInterfaceQueue(std::function<void ()> func) {
    g_signals.m_internals->m_schedulerClient.AddToProcessQueue(std::move(func));
}

void SyncWithValidationInterfaceQueue() {
    AssertLockNotHeld(cs_main);
    // Block until the validation queue drains
    std::promise<void> promise;
    CallFunctionInValidationInterfaceQueue([&promise] {
        promise.set_value();
    });
    promise.get_future().wait();
}

void CMainSignals::MempoolEntryRemoved(CTransactionRef ptx, MemPoolRemovalReason reason) {
    if (reason != MemPoolRemovalReason::BLOCK && reason != MemPoolRemovalReason::CONFLICT) {
        m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] {
            m_internals->TransactionRemovedFromMempool(ptx);
        });
    }
}

void CMainSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
    // Dependencies exist that require UpdatedBlockTip events to be delivered in the order in which
    // the chain actually updates. One way to ensure this is for the caller to invoke this signal
    // in the same critical section where the chain is updated

    m_internals->m_schedulerClient.AddToProcessQueue([pindexNew, pindexFork, fInitialDownload, this] {
        m_internals->UpdatedBlockTip(pindexNew, pindexFork, fInitialDownload);
    });
}

void CMainSignals::TransactionAddedToMempool(const CTransactionRef &ptx) {
    m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] {
        m_internals->TransactionAddedToMempool(ptx);
    });
}

void CMainSignals::BlockConnected(const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>>& pvtxConflicted) {
    m_internals->m_schedulerClient.AddToProcessQueue([pblock, pindex, pvtxConflicted, this] {
        m_internals->BlockConnected(pblock, pindex, *pvtxConflicted);
    });
}

void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock> &pblock) {
    m_internals->m_schedulerClient.AddToProcessQueue([pblock, this] {
        m_internals->BlockDisconnected(pblock);
    });
}

void CMainSignals::ChainStateFlushed(const CBlockLocator &locator) {
    m_internals->m_schedulerClient.AddToProcessQueue([locator, this] {
        m_internals->ChainStateFlushed(locator);
    });
}

void CMainSignals::Broadcast(int64_t nBestBlockTime, CConnman* connman) {
    m_internals->Broadcast(nBestBlockTime, connman);
}

void CMainSignals::BlockChecked(const CBlock& block, const CValidationState& state) {
    m_internals->BlockChecked(block, state);
}

void CMainSignals::NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock> &block) {
    m_internals->NewPoWValidBlock(pindex, block);
}
<commit_msg>Check m_internals in UnregisterValidationInterface<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2018 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <validationinterface.h>

#include <primitives/block.h>
#include <scheduler.h>
#include <txmempool.h>
#include <util/system.h>
#include <validation.h>

#include <list>
#include <atomic>
#include <future>
#include <utility>

#include <boost/signals2/signal.hpp>

struct ValidationInterfaceConnections {
    boost::signals2::scoped_connection UpdatedBlockTip;
    boost::signals2::scoped_connection TransactionAddedToMempool;
    boost::signals2::scoped_connection BlockConnected;
    boost::signals2::scoped_connection BlockDisconnected;
    boost::signals2::scoped_connection TransactionRemovedFromMempool;
    boost::signals2::scoped_connection ChainStateFlushed;
    boost::signals2::scoped_connection Broadcast;
    boost::signals2::scoped_connection BlockChecked;
    boost::signals2::scoped_connection NewPoWValidBlock;
};

struct MainSignalsInstance {
    boost::signals2::signal<void (const CBlockIndex *, const CBlockIndex *, bool fInitialDownload)> UpdatedBlockTip;
    boost::signals2::signal<void (const CTransactionRef &)> TransactionAddedToMempool;
    boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef>&)> BlockConnected;
    boost::signals2::signal<void (const std::shared_ptr<const CBlock> &)> BlockDisconnected;
    boost::signals2::signal<void (const CTransactionRef &)> TransactionRemovedFromMempool;
    boost::signals2::signal<void (const CBlockLocator &)> ChainStateFlushed;
    boost::signals2::signal<void (int64_t nBestBlockTime, CConnman* connman)> Broadcast;
    boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
    boost::signals2::signal<void (const CBlockIndex *, const std::shared_ptr<const CBlock>&)> NewPoWValidBlock;

    // We are not allowed to assume the scheduler only runs in one thread,
    // but must ensure all callbacks happen in-order, so we end up creating
    // our own queue here :(
    SingleThreadedSchedulerClient m_schedulerClient;
    std::unordered_map<CValidationInterface*, ValidationInterfaceConnections> m_connMainSignals;

    explicit MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {}
};

static CMainSignals g_signals;

// This map has to a separate global instead of a member of MainSignalsInstance,
// because RegisterWithMempoolSignals is currently called before RegisterBackgroundSignalScheduler,
// so MainSignalsInstance hasn't been created yet.
static std::unordered_map<CTxMemPool*, boost::signals2::scoped_connection> g_connNotifyEntryRemoved;

void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler) {
    assert(!m_internals);
    m_internals.reset(new MainSignalsInstance(&scheduler));
}

void CMainSignals::UnregisterBackgroundSignalScheduler() {
    m_internals.reset(nullptr);
}

void CMainSignals::FlushBackgroundCallbacks() {
    if (m_internals) {
        m_internals->m_schedulerClient.EmptyQueue();
    }
}

size_t CMainSignals::CallbacksPending() {
    if (!m_internals) return 0;
    return m_internals->m_schedulerClient.CallbacksPending();
}

void CMainSignals::RegisterWithMempoolSignals(CTxMemPool& pool) {
    g_connNotifyEntryRemoved.emplace(std::piecewise_construct,
        std::forward_as_tuple(&pool),
        std::forward_as_tuple(pool.NotifyEntryRemoved.connect(std::bind(&CMainSignals::MempoolEntryRemoved, this, std::placeholders::_1, std::placeholders::_2)))
    );
}

void CMainSignals::UnregisterWithMempoolSignals(CTxMemPool& pool) {
    g_connNotifyEntryRemoved.erase(&pool);
}

CMainSignals& GetMainSignals()
{
    return g_signals;
}

void RegisterValidationInterface(CValidationInterface* pwalletIn) {
    ValidationInterfaceConnections& conns = g_signals.m_internals->m_connMainSignals[pwalletIn];
    conns.UpdatedBlockTip = g_signals.m_internals->UpdatedBlockTip.connect(std::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    conns.TransactionAddedToMempool = g_signals.m_internals->TransactionAddedToMempool.connect(std::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, std::placeholders::_1));
    conns.BlockConnected = g_signals.m_internals->BlockConnected.connect(std::bind(&CValidationInterface::BlockConnected, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    conns.BlockDisconnected = g_signals.m_internals->BlockDisconnected.connect(std::bind(&CValidationInterface::BlockDisconnected, pwalletIn, std::placeholders::_1));
    conns.TransactionRemovedFromMempool = g_signals.m_internals->TransactionRemovedFromMempool.connect(std::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, std::placeholders::_1));
    conns.ChainStateFlushed = g_signals.m_internals->ChainStateFlushed.connect(std::bind(&CValidationInterface::ChainStateFlushed, pwalletIn, std::placeholders::_1));
    conns.Broadcast = g_signals.m_internals->Broadcast.connect(std::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, std::placeholders::_1, std::placeholders::_2));
    conns.BlockChecked = g_signals.m_internals->BlockChecked.connect(std::bind(&CValidationInterface::BlockChecked, pwalletIn, std::placeholders::_1, std::placeholders::_2));
    conns.NewPoWValidBlock = g_signals.m_internals->NewPoWValidBlock.connect(std::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, std::placeholders::_1, std::placeholders::_2));
}

void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
    if (g_signals.m_internals) {
        g_signals.m_internals->m_connMainSignals.erase(pwalletIn);
    }
}

void UnregisterAllValidationInterfaces() {
    if (!g_signals.m_internals) {
        return;
    }
    g_signals.m_internals->m_connMainSignals.clear();
}

void CallFunctionInValidationInterfaceQueue(std::function<void ()> func) {
    g_signals.m_internals->m_schedulerClient.AddToProcessQueue(std::move(func));
}

void SyncWithValidationInterfaceQueue() {
    AssertLockNotHeld(cs_main);
    // Block until the validation queue drains
    std::promise<void> promise;
    CallFunctionInValidationInterfaceQueue([&promise] {
        promise.set_value();
    });
    promise.get_future().wait();
}

void CMainSignals::MempoolEntryRemoved(CTransactionRef ptx, MemPoolRemovalReason reason) {
    if (reason != MemPoolRemovalReason::BLOCK && reason != MemPoolRemovalReason::CONFLICT) {
        m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] {
            m_internals->TransactionRemovedFromMempool(ptx);
        });
    }
}

void CMainSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
    // Dependencies exist that require UpdatedBlockTip events to be delivered in the order in which
    // the chain actually updates. One way to ensure this is for the caller to invoke this signal
    // in the same critical section where the chain is updated

    m_internals->m_schedulerClient.AddToProcessQueue([pindexNew, pindexFork, fInitialDownload, this] {
        m_internals->UpdatedBlockTip(pindexNew, pindexFork, fInitialDownload);
    });
}

void CMainSignals::TransactionAddedToMempool(const CTransactionRef &ptx) {
    m_internals->m_schedulerClient.AddToProcessQueue([ptx, this] {
        m_internals->TransactionAddedToMempool(ptx);
    });
}

void CMainSignals::BlockConnected(const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>>& pvtxConflicted) {
    m_internals->m_schedulerClient.AddToProcessQueue([pblock, pindex, pvtxConflicted, this] {
        m_internals->BlockConnected(pblock, pindex, *pvtxConflicted);
    });
}

void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock> &pblock) {
    m_internals->m_schedulerClient.AddToProcessQueue([pblock, this] {
        m_internals->BlockDisconnected(pblock);
    });
}

void CMainSignals::ChainStateFlushed(const CBlockLocator &locator) {
    m_internals->m_schedulerClient.AddToProcessQueue([locator, this] {
        m_internals->ChainStateFlushed(locator);
    });
}

void CMainSignals::Broadcast(int64_t nBestBlockTime, CConnman* connman) {
    m_internals->Broadcast(nBestBlockTime, connman);
}

void CMainSignals::BlockChecked(const CBlock& block, const CValidationState& state) {
    m_internals->BlockChecked(block, state);
}

void CMainSignals::NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock> &block) {
    m_internals->NewPoWValidBlock(pindex, block);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014-2015 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <iomanip>
#include <iostream>
#include <limits>

#include "ConsoleBotView.hpp"

static int numberOfDigits(int number) {
    int digits = 0;
    while (number) {
        number /= 10;
        digits++;
    }
    return digits;
}

static void printSpaces(int spaces) {
    for (int i = 0; i < spaces; i++) {
        std::cout << " ";
    }
}

void ConsoleBotView::view() {
    while (true) {
        start();
        char mode;
        std::cin >> mode;
        switch (mode) {
            case 't':
                gameWithTime();
                break;
            case 'w':
                gameForWin();
                break;
            case 's':
                gameForScore();
                break;
            case 'q':
                return;
            default:
                sendHelpMessage_impl();
        }
    }
}

void ConsoleBotView::timeNumberMessage() const {
    std::cout << "How many minutes you want to play?" << std::endl;
    std::cout << "The default is " << Rules::DEFAULT_TIME
              << std::endl;
    prompt();
}

void ConsoleBotView::winNumberMessage() const {
    int square = getBoardsSquare();
    std::cout << "What score you want to finish the "
                 "game?" << std::endl;
    std::cout << "The default is " << square * 4
              << std::endl;
    prompt();
}

void ConsoleBotView::deskSizeMessage() const {
    std::cout << "Please enter size of the game board."
              << std::endl;
    std::cout << "Your board will have x * x square."
              << std::endl;
    std::cout << "(Where x is input size)" << std::endl;
    std::cout << "Minimum size is " << Rules::MIN_WIDTH
              << " and maximum is " << Rules::MAX_WIDTH
              << std::endl;
    std::cout << "But try to choose size which "
                 "corresponds to the size of your screen."
              << std::endl;
    prompt();
}

void ConsoleBotView::outputGeneral() const {
    int max = maxDeskNumber();
    int digits = numberOfDigits(max);
    int row_number = game_->desk->getRowNumber();
    for (int i = row_number - 1; i >= 0; i--) {
        std::cout << std::right
                  << std::setw(Console::MAX_INDEX_LENGTH)
                  << i << " ||";
        for (int x = 0; x < row_number; x++) {
            Point point;
            point.col = i;
            point.row = x;
            int width = Console::NUMBER_OF_SPACES + digits;
            std::cout << std::right << std::setw(width)
                      << game_->desk->getDeskNumber(point);
        }
        std::cout << std::endl;
    }
}

void ConsoleBotView::prompt() const {
    std::cout << ">>> ";
}

void ConsoleBotView::typeError() const {
    std::cout << "Error: you must enter the NUMBER" << std::endl;
    std::cout << "Try again: " << std::endl;
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<int>::max(), '\n');
}

void ConsoleBotView::rangeError(TypeOfChecking type) const {
    int max_int = std::numeric_limits<int>::max();
    std::cout << "This number is out of allowable "
                 "range." << std::endl;
    if (type == TIME) {
        std::cout << "Please enter a POSITIVE INTEGER"
                  << std::endl;
        std::cout << "Maximum is " << max_int << std::endl;
    } else if (type == SCORE) {
        int square = getBoardsSquare();
        std::cout << "For this size of the game board "
                  << "minimum is " << square * 2 + 1
                  << std::endl;
        std::cout << "Maximum is " << max_int << std::endl;

    }
    std::cout << "Try again: " << std::endl;
    std::cin.clear();
    std::cin.ignore(max_int, '\n');
}

bool ConsoleBotView::checkRange(int verifiable,
                                TypeOfChecking type) const {
    switch (type) {
        case BOARDS_SIZE:
            return ((verifiable >= Rules::MIN_WIDTH) &&
                    (verifiable <= Rules::MAX_WIDTH));
        case TIME:
            // By checking that verifiable is greater than
            // zero we make sure that it's less or equal
            // to the allowable maximum for int also.
            // See cyclic mechanism of ints in C++.
            return (verifiable > 0);
        case SCORE:
            int square = getBoardsSquare();
            return (verifiable > square * 2);
    }
}

int ConsoleBotView::getBoardsSquare() const {
    int boards_size = game_->desk->getRowNumber();
    return boards_size * boards_size;
}

const GameDesk* ConsoleBotView::getDesk() const {
    return game_->desk.data();
}

void ConsoleBotView::finish_impl(bool fail, int score,
                                 int steps_number) const {
    if (fail) {
        std::cout << "You are loser... Your score is " << score << std::endl;
    } else {
        std::cout << "You are winner! Your score is " << score << std::endl;
    }
    std::cout << "You have completed the game in " << steps_number << " steps." << std::endl;
}

void ConsoleBotView::sendHelpMessage_impl() const {
    std::cout << "You must enter t, w, s or q" << std::endl;
    std::cout << "Try again please." << std::endl;
}

void ConsoleBotView::startGame_impl(int row_number) {
    try {
        game_ = Game::make(row_number);
        game_->controller->initialStateOfBoard();
    } catch (std::exception& e) {
        errorHandling_impl(e);
    }
}

void ConsoleBotView::errorHandling_impl(std::exception& e) const {
    std::cout << e.what() << std::endl;
}

int ConsoleBotView::maxDeskNumber() const {
    const GameDesk* desk = game_->desk.data();
    int boards_size = desk->getRowNumber();
    int max = 0;
    for (int i = boards_size - 1; i >= 0; i--) {
        for (int x = 0; x < boards_size; x++) {
            Point pt;
            pt.col = i;
            pt.row = x;
            int current_number = desk->getDeskNumber(pt);
            if (current_number > max) {
                max = current_number;
            }
        }
    }
    return max;
}

void ConsoleBotView::rowIndices(int width) const {
    int boards_size = game_->desk->getRowNumber();
    for (int i = 0; i < width * boards_size; i++) {
        std::cout << "=";
    }
    std::cout << std::endl;
    for (int i = 0; i < boards_size; i++) {
        std::cout << std::right << std::setw(width) << i;
    }
}

void ConsoleBotView::start() const {
    std::cout << "*** BIN_GAME ***" << std::endl;
    std::cout << "----------------" << std::endl;
    std::cout << "t: time mode | w: play for score | s: "
                 "play while not lose" << std::endl;
    std::cout << "q: quit" << std::endl;
    prompt();
}

void ConsoleBotView::gameForWin() {
    int desk_size = getDeskSize_impl();
    startGame_impl(desk_size);
    int win_number = getWinNumber_impl();
    const GameDesk* desk = game_->desk.data();
    output_impl();
    int steps_number = 0;
    while (!checkFail(*desk) && !checkWin(*desk,
                                          win_number)) {
        steps_number += 1;
        play();
    }
    finish_impl(checkFail(*desk), score(*desk),
                steps_number);
}

void ConsoleBotView::gameForScore() {
    int desk_size = getDeskSize_impl();
    startGame_impl(desk_size);
    const GameDesk* desk = game_->desk.data();
    output_impl();
    int steps_number = 0;
    while (!checkFail(*desk)) {
        steps_number += 1;
        play();
    }
    finish_impl(checkFail(*desk), score(*desk),
                steps_number);
}

void ConsoleBotView::gameWithTime() {
    int desk_size = getDeskSize_impl();
    int time_number = getTimeNumber_impl();
    startGame_impl(desk_size);
    int t1 = time(NULL);
    int t2 = 0;
    const GameDesk* desk = game_->desk.data();
    output_impl();
    int steps_number = 0;
    while (!checkFail(*desk) &&
           ((t2 - t1) < time_number * 60)) {
        steps_number += 1;
        play();
        t2 = time(NULL);
    }
    finish_impl(checkFail(*desk), score(*desk),
                steps_number);
}

void ConsoleBotView::play() {
    Points points = getIndex_impl();
    try {
        game_->controller->replace(points);
    } catch (std::exception& e) {
        errorHandling_impl(e);
    }
    output_impl();
}
<commit_msg>Call printSpaces() from ConsoleBotView::rowIndices<commit_after>/*
 * Copyright (C) 2014-2015 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

#include <iomanip>
#include <iostream>
#include <limits>

#include "ConsoleBotView.hpp"

static int numberOfDigits(int number) {
    int digits = 0;
    while (number) {
        number /= 10;
        digits++;
    }
    return digits;
}

static void printSpaces(int spaces) {
    for (int i = 0; i < spaces; i++) {
        std::cout << " ";
    }
}

void ConsoleBotView::view() {
    while (true) {
        start();
        char mode;
        std::cin >> mode;
        switch (mode) {
            case 't':
                gameWithTime();
                break;
            case 'w':
                gameForWin();
                break;
            case 's':
                gameForScore();
                break;
            case 'q':
                return;
            default:
                sendHelpMessage_impl();
        }
    }
}

void ConsoleBotView::timeNumberMessage() const {
    std::cout << "How many minutes you want to play?" << std::endl;
    std::cout << "The default is " << Rules::DEFAULT_TIME
              << std::endl;
    prompt();
}

void ConsoleBotView::winNumberMessage() const {
    int square = getBoardsSquare();
    std::cout << "What score you want to finish the "
                 "game?" << std::endl;
    std::cout << "The default is " << square * 4
              << std::endl;
    prompt();
}

void ConsoleBotView::deskSizeMessage() const {
    std::cout << "Please enter size of the game board."
              << std::endl;
    std::cout << "Your board will have x * x square."
              << std::endl;
    std::cout << "(Where x is input size)" << std::endl;
    std::cout << "Minimum size is " << Rules::MIN_WIDTH
              << " and maximum is " << Rules::MAX_WIDTH
              << std::endl;
    std::cout << "But try to choose size which "
                 "corresponds to the size of your screen."
              << std::endl;
    prompt();
}

void ConsoleBotView::outputGeneral() const {
    int max = maxDeskNumber();
    int digits = numberOfDigits(max);
    int row_number = game_->desk->getRowNumber();
    for (int i = row_number - 1; i >= 0; i--) {
        std::cout << std::right
                  << std::setw(Console::MAX_INDEX_LENGTH)
                  << i << " ||";
        for (int x = 0; x < row_number; x++) {
            Point point;
            point.col = i;
            point.row = x;
            int width = Console::NUMBER_OF_SPACES + digits;
            std::cout << std::right << std::setw(width)
                      << game_->desk->getDeskNumber(point);
        }
        std::cout << std::endl;
    }
}

void ConsoleBotView::prompt() const {
    std::cout << ">>> ";
}

void ConsoleBotView::typeError() const {
    std::cout << "Error: you must enter the NUMBER" << std::endl;
    std::cout << "Try again: " << std::endl;
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<int>::max(), '\n');
}

void ConsoleBotView::rangeError(TypeOfChecking type) const {
    int max_int = std::numeric_limits<int>::max();
    std::cout << "This number is out of allowable "
                 "range." << std::endl;
    if (type == TIME) {
        std::cout << "Please enter a POSITIVE INTEGER"
                  << std::endl;
        std::cout << "Maximum is " << max_int << std::endl;
    } else if (type == SCORE) {
        int square = getBoardsSquare();
        std::cout << "For this size of the game board "
                  << "minimum is " << square * 2 + 1
                  << std::endl;
        std::cout << "Maximum is " << max_int << std::endl;

    }
    std::cout << "Try again: " << std::endl;
    std::cin.clear();
    std::cin.ignore(max_int, '\n');
}

bool ConsoleBotView::checkRange(int verifiable,
                                TypeOfChecking type) const {
    switch (type) {
        case BOARDS_SIZE:
            return ((verifiable >= Rules::MIN_WIDTH) &&
                    (verifiable <= Rules::MAX_WIDTH));
        case TIME:
            // By checking that verifiable is greater than
            // zero we make sure that it's less or equal
            // to the allowable maximum for int also.
            // See cyclic mechanism of ints in C++.
            return (verifiable > 0);
        case SCORE:
            int square = getBoardsSquare();
            return (verifiable > square * 2);
    }
}

int ConsoleBotView::getBoardsSquare() const {
    int boards_size = game_->desk->getRowNumber();
    return boards_size * boards_size;
}

const GameDesk* ConsoleBotView::getDesk() const {
    return game_->desk.data();
}

void ConsoleBotView::finish_impl(bool fail, int score,
                                 int steps_number) const {
    if (fail) {
        std::cout << "You are loser... Your score is " << score << std::endl;
    } else {
        std::cout << "You are winner! Your score is " << score << std::endl;
    }
    std::cout << "You have completed the game in " << steps_number << " steps." << std::endl;
}

void ConsoleBotView::sendHelpMessage_impl() const {
    std::cout << "You must enter t, w, s or q" << std::endl;
    std::cout << "Try again please." << std::endl;
}

void ConsoleBotView::startGame_impl(int row_number) {
    try {
        game_ = Game::make(row_number);
        game_->controller->initialStateOfBoard();
    } catch (std::exception& e) {
        errorHandling_impl(e);
    }
}

void ConsoleBotView::errorHandling_impl(std::exception& e) const {
    std::cout << e.what() << std::endl;
}

int ConsoleBotView::maxDeskNumber() const {
    const GameDesk* desk = game_->desk.data();
    int boards_size = desk->getRowNumber();
    int max = 0;
    for (int i = boards_size - 1; i >= 0; i--) {
        for (int x = 0; x < boards_size; x++) {
            Point pt;
            pt.col = i;
            pt.row = x;
            int current_number = desk->getDeskNumber(pt);
            if (current_number > max) {
                max = current_number;
            }
        }
    }
    return max;
}

void ConsoleBotView::rowIndices(int width) const {
    int boards_size = game_->desk->getRowNumber();
    printSpaces(Console::INDEX_FIELD);
    for (int i = 0; i < width * boards_size; i++) {
        std::cout << "=";
    }
    std::cout << std::endl;
    printSpaces(Console::INDEX_FIELD);
    for (int i = 0; i < boards_size; i++) {
        std::cout << std::right << std::setw(width) << i;
    }
}

void ConsoleBotView::start() const {
    std::cout << "*** BIN_GAME ***" << std::endl;
    std::cout << "----------------" << std::endl;
    std::cout << "t: time mode | w: play for score | s: "
                 "play while not lose" << std::endl;
    std::cout << "q: quit" << std::endl;
    prompt();
}

void ConsoleBotView::gameForWin() {
    int desk_size = getDeskSize_impl();
    startGame_impl(desk_size);
    int win_number = getWinNumber_impl();
    const GameDesk* desk = game_->desk.data();
    output_impl();
    int steps_number = 0;
    while (!checkFail(*desk) && !checkWin(*desk,
                                          win_number)) {
        steps_number += 1;
        play();
    }
    finish_impl(checkFail(*desk), score(*desk),
                steps_number);
}

void ConsoleBotView::gameForScore() {
    int desk_size = getDeskSize_impl();
    startGame_impl(desk_size);
    const GameDesk* desk = game_->desk.data();
    output_impl();
    int steps_number = 0;
    while (!checkFail(*desk)) {
        steps_number += 1;
        play();
    }
    finish_impl(checkFail(*desk), score(*desk),
                steps_number);
}

void ConsoleBotView::gameWithTime() {
    int desk_size = getDeskSize_impl();
    int time_number = getTimeNumber_impl();
    startGame_impl(desk_size);
    int t1 = time(NULL);
    int t2 = 0;
    const GameDesk* desk = game_->desk.data();
    output_impl();
    int steps_number = 0;
    while (!checkFail(*desk) &&
           ((t2 - t1) < time_number * 60)) {
        steps_number += 1;
        play();
        t2 = time(NULL);
    }
    finish_impl(checkFail(*desk), score(*desk),
                steps_number);
}

void ConsoleBotView::play() {
    Points points = getIndex_impl();
    try {
        game_->controller->replace(points);
    } catch (std::exception& e) {
        errorHandling_impl(e);
    }
    output_impl();
}
<|endoftext|>