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

#include <stdio.h>

// #include <osl/diagnose.h>
#include <rtl/byteseq.hxx>

using namespace ::rtl;

#include <cppunit/simpleheader.hxx>

namespace rtl_testbyteseq
{

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

class oldbyteseq : public CppUnit::TestFixture
{
public:
    void test_bytesequence_001();

    CPPUNIT_TEST_SUITE( oldbyteseq );
    CPPUNIT_TEST( test_bytesequence_001 );
    CPPUNIT_TEST_SUITE_END( );
};

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

void oldbyteseq::test_bytesequence_001()
{
    signed char a[5] = { 1 , 2 , 3 , 4 , 5 };

    // test the c++ wrapper
    {
        ByteSequence seq;
        OSL_ENSURE( ! seq.getLength() , "" );

        ByteSequence seq2( a , 5 );

        OSL_ENSURE( !( seq == seq2) , "" );

        seq = seq2;
        OSL_ENSURE( seq == seq2 , "" );

        seq[0] = 2;
        OSL_ENSURE( !(seq == seq2) , "" );

        seq = ByteSequence( a , 5 );
        OSL_ENSURE( seq == seq2 , "" );

        seq = ByteSequence( 5 ); // default value is 0 for each byte
        OSL_ENSURE( !( seq == seq2 ) , "" );
    }

    {
        sal_Sequence *pSeq = 0;
        rtl_byte_sequence_construct( &pSeq , 0 );

        // implementation dependent test.
        OSL_ENSURE( pSeq->nRefCount == 2 , "invalid refcount for empty sequence" );

        sal_Sequence *pSeq2 = 0;
        rtl_byte_sequence_constructFromArray( &pSeq2 , a , 5 );

        OSL_ENSURE( ! rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_assign( &pSeq , pSeq2 );
        OSL_ENSURE( pSeq == pSeq2 , "" );
        OSL_ENSURE( rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_reference2One( &pSeq );
        (( sal_Int8*) rtl_byte_sequence_getConstArray( pSeq ) )[0] = 2;

        OSL_ENSURE( ! rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_constructFromArray( &pSeq , a , 5 );
        OSL_ENSURE( rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_construct( &pSeq , 5 );
        OSL_ENSURE( ! rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_release( pSeq2 );
        rtl_byte_sequence_release( pSeq );
    }

    printf( "test bytesequence OK\n" );

}

} // namespace osl_test_file

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( rtl_testbyteseq::oldbyteseq, "rtl_ByteSequence" );

// -----------------------------------------------------------------------------
NOADDITIONAL;
<commit_msg>INTEGRATION: CWS ooo19126 (1.2.162); FILE MERGED 2005/09/05 17:44:40 rt 1.2.162.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: rtl_old_testbyteseq.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 15:15:15 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
// LLA:
// this file is converted to use with testshl2
// original was placed in sal/test/textenc.cxx
// -----------------------------------------------------------------------------

#include <stdio.h>

// #include <osl/diagnose.h>
#include <rtl/byteseq.hxx>

using namespace ::rtl;

#include <cppunit/simpleheader.hxx>

namespace rtl_testbyteseq
{

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

class oldbyteseq : public CppUnit::TestFixture
{
public:
    void test_bytesequence_001();

    CPPUNIT_TEST_SUITE( oldbyteseq );
    CPPUNIT_TEST( test_bytesequence_001 );
    CPPUNIT_TEST_SUITE_END( );
};

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

void oldbyteseq::test_bytesequence_001()
{
    signed char a[5] = { 1 , 2 , 3 , 4 , 5 };

    // test the c++ wrapper
    {
        ByteSequence seq;
        OSL_ENSURE( ! seq.getLength() , "" );

        ByteSequence seq2( a , 5 );

        OSL_ENSURE( !( seq == seq2) , "" );

        seq = seq2;
        OSL_ENSURE( seq == seq2 , "" );

        seq[0] = 2;
        OSL_ENSURE( !(seq == seq2) , "" );

        seq = ByteSequence( a , 5 );
        OSL_ENSURE( seq == seq2 , "" );

        seq = ByteSequence( 5 ); // default value is 0 for each byte
        OSL_ENSURE( !( seq == seq2 ) , "" );
    }

    {
        sal_Sequence *pSeq = 0;
        rtl_byte_sequence_construct( &pSeq , 0 );

        // implementation dependent test.
        OSL_ENSURE( pSeq->nRefCount == 2 , "invalid refcount for empty sequence" );

        sal_Sequence *pSeq2 = 0;
        rtl_byte_sequence_constructFromArray( &pSeq2 , a , 5 );

        OSL_ENSURE( ! rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_assign( &pSeq , pSeq2 );
        OSL_ENSURE( pSeq == pSeq2 , "" );
        OSL_ENSURE( rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_reference2One( &pSeq );
        (( sal_Int8*) rtl_byte_sequence_getConstArray( pSeq ) )[0] = 2;

        OSL_ENSURE( ! rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_constructFromArray( &pSeq , a , 5 );
        OSL_ENSURE( rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_construct( &pSeq , 5 );
        OSL_ENSURE( ! rtl_byte_sequence_equals( pSeq , pSeq2 ) , "" );

        rtl_byte_sequence_release( pSeq2 );
        rtl_byte_sequence_release( pSeq );
    }

    printf( "test bytesequence OK\n" );

}

} // namespace osl_test_file

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( rtl_testbyteseq::oldbyteseq, "rtl_ByteSequence" );

// -----------------------------------------------------------------------------
NOADDITIONAL;
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

/**

\author Radu Bogdan Rusu

**/

#include "pcl/pcl_base.h"

//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PCLBase<sensor_msgs::PointCloud2>::setInputCloud (const PointCloud2ConstPtr &cloud)
{
  input_ = cloud;

  for (size_t d = 0; d < cloud->fields.size (); ++d)
  {
    if (cloud->fields[d].name == x_field_name_)
      x_idx_ = d;
    if (cloud->fields[d].name == y_field_name_)
      y_idx_ = d;
    if (cloud->fields[d].name == z_field_name_)
      z_idx_ = d;
  }

  // Obtain the size of all fields. Restrict to sizeof FLOAT32 for now
  field_sizes_.resize (input_->fields.size ());
  for (size_t d = 0; d < input_->fields.size (); ++d)
  {
    int fsize;
    switch (input_->fields[d].datatype)
    {
      case sensor_msgs::PointField::INT8:
      case sensor_msgs::PointField::UINT8:
      {
        fsize = 1;
        break;
      }

      case sensor_msgs::PointField::INT16:
      case sensor_msgs::PointField::UINT16:
      {
        fsize = 2;
        break;
      }

      case sensor_msgs::PointField::INT32:
      case sensor_msgs::PointField::UINT32:
      case sensor_msgs::PointField::FLOAT32:
      {
        fsize = 4;
        break;
      }

      case sensor_msgs::PointField::FLOAT64:
      {
        fsize = 8;
        break;
      }

      default:
      {
        PCL_ERROR ("[PCLBase::setInputCloud] Invalid field type (%d)!\n", input_->fields[d].datatype);
        fsize = 0;
        break;
      }
    }
    field_sizes_[d] = (std::min) (fsize, (int)sizeof (float));
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PCLBase<sensor_msgs::PointCloud2>::deinitCompute ()
{
  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PCLBase<sensor_msgs::PointCloud2>::initCompute ()
{
  // Check if input was set
  if (!input_)
    return (false);

  // If no point indices have been given, construct a set of indices for the entire input point cloud
  if (!indices_)
  {
    fake_indices_ = true;
    indices_.reset (new std::vector<int>);
    try
    {
      indices_->resize (input_->width * input_->height);
    }
    catch (std::bad_alloc)
    {
      PCL_ERROR ("[initCompute] Failed to allocate %lu indices.\n", (unsigned long) (input_->width * input_->height));
    }
    for (size_t i = 0; i < indices_->size (); ++i) { (*indices_)[i] = i; }
  }
  // If we have a set of fake indices, but they do not match the number of points in the cloud, update them
  if (fake_indices_ && indices_->size () != (input_->width * input_->height))
  {
    size_t indices_size = indices_->size ();
    indices_->resize (input_->width * input_->height);
    for (size_t i = indices_size; i < indices_->size (); ++i) { (*indices_)[i] = i; }
  }

  return (true);
}

<commit_msg>license change<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#include "pcl/pcl_base.h"

//////////////////////////////////////////////////////////////////////////////////////////////
void
pcl::PCLBase<sensor_msgs::PointCloud2>::setInputCloud (const PointCloud2ConstPtr &cloud)
{
  input_ = cloud;

  for (size_t d = 0; d < cloud->fields.size (); ++d)
  {
    if (cloud->fields[d].name == x_field_name_)
      x_idx_ = d;
    if (cloud->fields[d].name == y_field_name_)
      y_idx_ = d;
    if (cloud->fields[d].name == z_field_name_)
      z_idx_ = d;
  }

  // Obtain the size of all fields. Restrict to sizeof FLOAT32 for now
  field_sizes_.resize (input_->fields.size ());
  for (size_t d = 0; d < input_->fields.size (); ++d)
  {
    int fsize;
    switch (input_->fields[d].datatype)
    {
      case sensor_msgs::PointField::INT8:
      case sensor_msgs::PointField::UINT8:
      {
        fsize = 1;
        break;
      }

      case sensor_msgs::PointField::INT16:
      case sensor_msgs::PointField::UINT16:
      {
        fsize = 2;
        break;
      }

      case sensor_msgs::PointField::INT32:
      case sensor_msgs::PointField::UINT32:
      case sensor_msgs::PointField::FLOAT32:
      {
        fsize = 4;
        break;
      }

      case sensor_msgs::PointField::FLOAT64:
      {
        fsize = 8;
        break;
      }

      default:
      {
        PCL_ERROR ("[PCLBase::setInputCloud] Invalid field type (%d)!\n", input_->fields[d].datatype);
        fsize = 0;
        break;
      }
    }
    field_sizes_[d] = (std::min) (fsize, (int)sizeof (float));
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PCLBase<sensor_msgs::PointCloud2>::deinitCompute ()
{
  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
bool
pcl::PCLBase<sensor_msgs::PointCloud2>::initCompute ()
{
  // Check if input was set
  if (!input_)
    return (false);

  // If no point indices have been given, construct a set of indices for the entire input point cloud
  if (!indices_)
  {
    fake_indices_ = true;
    indices_.reset (new std::vector<int>);
    try
    {
      indices_->resize (input_->width * input_->height);
    }
    catch (std::bad_alloc)
    {
      PCL_ERROR ("[initCompute] Failed to allocate %lu indices.\n", (unsigned long) (input_->width * input_->height));
    }
    for (size_t i = 0; i < indices_->size (); ++i) { (*indices_)[i] = i; }
  }
  // If we have a set of fake indices, but they do not match the number of points in the cloud, update them
  if (fake_indices_ && indices_->size () != (input_->width * input_->height))
  {
    size_t indices_size = indices_->size ();
    indices_->resize (input_->width * input_->height);
    for (size_t i = indices_size; i < indices_->size (); ++i) { (*indices_)[i] = i; }
  }

  return (true);
}

<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2012 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/version.h>

#include <vistk/version.h>

#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>

/**
 * \file version.cxx
 *
 * \brief Python bindings for version.
 */

using namespace boost::python;

class compile
{
  public:
    typedef vistk::version::version_t version_t;

    static bool check(version_t major_, version_t minor_, version_t patch_);
};

class runtime
{
};

BOOST_PYTHON_MODULE(version)
{
  class_<compile>("compile"
    , "Compile-time version information."
    , no_init)
    .def_readonly("major", VISTK_VERSION_MAJOR)
    .def_readonly("minor", VISTK_VERSION_MINOR)
    .def_readonly("patch", VISTK_VERSION_PATCH)
    .def_readonly("version_string", VISTK_VERSION)
    .def_readonly("git_build",
#ifdef VISTK_BUILT_FROM_GIT
      true
#else
      false
#endif
    )
    .def_readonly("git_hash", VISTK_GIT_HASH)
    .def_readonly("git_hash_short", VISTK_GIT_HASH_SHORT)
    .def_readonly("git_dirty", VISTK_GIT_DIRTY)
    .def("check", &compile::check
      , (arg("major"), arg("minor"), arg("patch"))
      , "Check for a vistk of at least the given version.")
    .staticmethod("check")
  ;

  class_<runtime>("runtime"
    , "Runtime version information."
    , no_init)
    .def_readonly("major", vistk::version::major)
    .def_readonly("minor", vistk::version::minor)
    .def_readonly("patch", vistk::version::patch)
    .def_readonly("version_string", vistk::version::version_string)
    .def_readonly("git_build", vistk::version::git_build)
    .def_readonly("git_hash", vistk::version::git_hash)
    .def_readonly("git_hash_short", vistk::version::git_hash_short)
    .def_readonly("git_dirty", vistk::version::git_dirty)
    .def("check", &vistk::version::check
      , (arg("major"), arg("minor"), arg("patch"))
      , "Check for a vistk of at least the given version.")
    .staticmethod("check")
  ;
}

bool
compile
::check(version_t major_, version_t minor_, version_t patch_)
{
  // If any of the version components are 0, we get compare warnings. Turn
  // them off here.
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
#endif

  return VISTK_VERSION_CHECK(major_, minor_, patch_);

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
}
<commit_msg>Move warning pragmas outside the function body<commit_after>/*ckwg +5
 * Copyright 2012 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/version.h>

#include <vistk/version.h>

#include <boost/python/class.hpp>
#include <boost/python/def.hpp>
#include <boost/python/module.hpp>

/**
 * \file version.cxx
 *
 * \brief Python bindings for version.
 */

using namespace boost::python;

class compile
{
  public:
    typedef vistk::version::version_t version_t;

    static bool check(version_t major_, version_t minor_, version_t patch_);
};

class runtime
{
};

BOOST_PYTHON_MODULE(version)
{
  class_<compile>("compile"
    , "Compile-time version information."
    , no_init)
    .def_readonly("major", VISTK_VERSION_MAJOR)
    .def_readonly("minor", VISTK_VERSION_MINOR)
    .def_readonly("patch", VISTK_VERSION_PATCH)
    .def_readonly("version_string", VISTK_VERSION)
    .def_readonly("git_build",
#ifdef VISTK_BUILT_FROM_GIT
      true
#else
      false
#endif
    )
    .def_readonly("git_hash", VISTK_GIT_HASH)
    .def_readonly("git_hash_short", VISTK_GIT_HASH_SHORT)
    .def_readonly("git_dirty", VISTK_GIT_DIRTY)
    .def("check", &compile::check
      , (arg("major"), arg("minor"), arg("patch"))
      , "Check for a vistk of at least the given version.")
    .staticmethod("check")
  ;

  class_<runtime>("runtime"
    , "Runtime version information."
    , no_init)
    .def_readonly("major", vistk::version::major)
    .def_readonly("minor", vistk::version::minor)
    .def_readonly("patch", vistk::version::patch)
    .def_readonly("version_string", vistk::version::version_string)
    .def_readonly("git_build", vistk::version::git_build)
    .def_readonly("git_hash", vistk::version::git_hash)
    .def_readonly("git_hash_short", vistk::version::git_hash_short)
    .def_readonly("git_dirty", vistk::version::git_dirty)
    .def("check", &vistk::version::check
      , (arg("major"), arg("minor"), arg("patch"))
      , "Check for a vistk of at least the given version.")
    .staticmethod("check")
  ;
}

// If any of the version components are 0, we get compare warnings. Turn
// them off here.
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
#endif

bool
compile
::check(version_t major_, version_t minor_, version_t patch_)
{
  return VISTK_VERSION_CHECK(major_, minor_, patch_);
}

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
<|endoftext|>


<commit_before>/* Copyright (c) 2017 Wenova - Rise of Conquerors. All rights reserved.
 *
 * This work is licensed under the terms of the MIT license.
 * For a copy, see <https://opensource.org/licenses/MIT>.
 */
/**
 * @file EditableFloor.cpp
 * Implements class EditableFloor methods.
 */

/**
 * Commented debugs should be used with extreme care because it causes
 * extremelly lose of performance and giant log files.
 */

#include "EditableFloor.h"

#include "Collision.h"
#include "InputManager.h"
#include "Rectangle.h"

#include <cstdio>

#define BACKGROUND_WIDTH 1280
#define BACKGROUND_HEIGHT 720

#define RESIZING_SPEED 0.005
#define ROTATING_SPEED 0.01
#define MOVE_SPEED 0.5

#define ACCELERATION 1
#define MAXIMUM_ACCELERATION 4
#define ACCELERATION_INCREASE_STEP 0.2

#define RIGID_PLATFORM_PATH "edit_state/floor/editable_floor.png"
#define CROSSINGABLE_PLATFORM_PATH "edit_state/floor/editable_platform.png"
#define SELECTED_CROSSINGABLE_PLATFORM_PATH \
    "edit_state/floor/selected_editable_floor.png"

#define DEBUG_SIZE 500
#define FILL_MISSING_PIXELS_DEBUGRMATIONS 15

#define LAYER 0
#define FLOOR_INITIAL_WIDTH 100
#define PI 3.14159265358979
#define PI_DEGREES 180

/**
 * Create box with default width of 100px.
 *
 * @param x Position in X axis. Unit: px, [0,screen_width]
 * @param y Position in Y axis. Unit: px, [0,screen_height]
 * @param crotation Unit: degrees
 * @param cplatform [0,1]
 */
EditableFloor::EditableFloor(float x, float y, float crotation, bool cplatform)
    : Floor(x, y, FLOOR_INITIAL_WIDTH, crotation, cplatform),
      standard_sprite(Sprite(RIGID_PLATFORM_PATH)),
      platform_sprite(Sprite(CROSSINGABLE_PLATFORM_PATH)),
      selected_sprite(Sprite(SELECTED_CROSSINGABLE_PLATFORM_PATH)) {
#ifndef NDEBUG
    std::string log_message = "Starting EditableFloor constructor with x: ";
    log_message += std::to_string(x) + ", y: " + std::to_string(y);
    log_message += ", crotation: " + std::to_string(crotation);
    log_message +=
        ", cplatfrom: " + std::to_string(static_cast<int>(cplatform));

    LOG(DEBUG) << log_message;
#endif

    box = Rectangle(x, y, standard_sprite.get_width(),
                    standard_sprite.get_height());

    is_deleted = false;
    is_selected = false;

    LOG(DEBUG) << "Ending EditableFloor constructor";
}

/**
 * Create box with specific width.
 *
 * @param x Position in X axis. Unit: px, [0,screen_width]
 * @param y Position in Y axis. Unit: px, [0,screen_height]
 * @param width Unit: px, [0,]
 * @param crotation Unit: degrees
 * @param cplatform [0,1]
 */
EditableFloor::EditableFloor(float x, float y, float width, float crotation,
                             bool cplatform)
    : EditableFloor(x, y, crotation, cplatform) {
#ifndef NDEBUG
    std::string log_message = "Starting EditableFloor constructor with x: ";
    log_message += std::to_string(x) + ", y: " + std::to_string(y);
    log_message += ", width:" + std::to_string(width);
    log_message += ", crotation: " + std::to_string(crotation);
    log_message +=
        ", cplatfrom: " + std::to_string(static_cast<int>(cplatform));
    LOG(DEBUG) << log_message;

    if (x <= BACKGROUND_WIDTH) {
        /* Nothing to do. */
    } else {
        LOG(FATAL) << "platform is out of screen in axis x";
    }

    if (x <= BACKGROUND_WIDTH) {
        /* Nothing to do. */
    } else {
        LOG(FATAL) << "platform is out of screen in axis y";
    }
#endif

    standard_sprite.set_scale_x(width / standard_sprite.get_width());
    platform_sprite.set_scale_x(width / platform_sprite.get_width());
    selected_sprite.set_scale_x(width / selected_sprite.get_width());

    box.width = standard_sprite.get_width();

    LOG(DEBUG) << "Ending EditableFloor init";
}

/**
 * Not implemented.
 */
EditableFloor::~EditableFloor() {
}

/**
 * Get information about many aspects of an box.
 *
 * @returns String in format: "x y width rotated level is_crossingable?"
 */
string EditableFloor::get_information() {
    LOG(DEBUG) << "Starting EditableFloor get_information";

    char info_c[DEBUG_SIZE];
    snprintf(info_c, sizeof(info_c), "%f %f %f %f %d", box.x, box.y, box.width,
             rotation * PI_DEGREES / PI, static_cast<int>(is_crossingable));

    string info(info_c);

    for (auto &c : info) {
        c += FILL_MISSING_PIXELS_DEBUGRMATIONS;
    }

    string return_value = info;

    /*
     * Check if string reallyhas the elements.
     * info == info_c for sure
     */
    float float1, float2, float3, float4;
    int int1;
    if (sscanf(info_c, "%f %f %f %f %d", &float1, &float2, &float3, &float4,
               &int1) == 5) {
        /* Nothing to do. */
    } else {
        LOG(WARNING) << "Info doesn't has all the information it should have";
    }

    std::string log_message =
        "Ending EditableFloor get_information returning value: " + return_value;
    LOG(DEBUG) << log_message;

    return return_value;
}

/**
 * Select elements which will be edited.
 *
 * @param cis_selected [0,1]
 */
void EditableFloor::set_selected(bool cis_selected) {
#ifndef NDEBUG
    std::string log_message =
        "Starting EditableFloor set_selected with cis_selected: " +
        static_cast<int>(cis_selected);
    LOG(DEBUG) << log_message;
#endif

    is_selected = cis_selected;

    LOG(DEBUG) << "Ending EditableFloor set_selected";
}

/**
 * Render selected box considering if it is selected.
 */
void EditableFloor::render() {
    // LOG(DEBUG) << "Starting EditableFloor render";

    if (is_selected) {
        selected_sprite.render(box.get_draw_x(), box.get_draw_y(), rotation);
    } else {
        /* Nothing to do. */
    }

    if (is_crossingable) {
        platform_sprite.render(box.get_draw_x(), box.get_draw_y(), rotation);
    } else {
        standard_sprite.render(box.get_draw_x(), box.get_draw_y(), rotation);
    }

    // LOG(DEBUG) << "Ending EditableFloor render";
}

/**
 * Manages player interaction with the box.
 *
 * @param delta_time Difference in position of the box.
 */
void EditableFloor::update(float delta_time) {
    /*
    #ifndef NDEBUG
    char log_message_c[60];
    snprintf(log_message_c, sizeof(log_message_c), "Starting EditableFloor
    update with delta_time: %.2f", delta_time);

    std::string log_message(log_message_c);
    LOG(DEBUG) << log_message;
    #endif
    */

    handle_platforms_interaction(delta_time);

    // LOG(DEBUG) << "Ending EditableFloor update";
}

/**
 * True if box has been deleted.
 *
 * @returns [0,1]
 */
bool EditableFloor::is_dead() {
    // LOG(DEBUG) << "Starting EditableFloor is_dead";

    bool return_value = is_deleted;

    /*
    #ifndef NDEBUG
    std::string log_message = "Ending EditableFloor is_dead returning value: " +
    std::to_string(static_cast<int>(return_value));
    LOG(DEBUG) << log_message;
    #endif
    */

    return return_value;
}

/**
 * Will handle all interaction of the user with the platform.
 *
 * @param delta_time time spent on each frame of sprites
 */
void EditableFloor::handle_platforms_interaction(float delta_time) {
    // LOG(DEBUG) << "Starting EditableFloor handle_platforms_interaction
    // method";

    InputManager *input_manager = InputManager::get_instance();

    if (input_manager->mouse_press(InputManager::LEFT_MOUSE_BUTTON)) {
        int x = input_manager->get_mouse_x_position();
        int y = input_manager->get_mouse_y_position();

        Rectangle mouse = Rectangle(x, y, 1, 1);
        is_selected = Collision::is_colliding(box, mouse, rotation, 0);
    } else {
        /* Nothing to do. */
    }

    if (is_selected) {
        static float acceleration = ACCELERATION;
        float delta_space = MOVE_SPEED * delta_time * acceleration;
        bool moved = false;

        handle_box_moving(moved, delta_space);
        handle_box_resizing(moved, delta_time);
        handle_box_rotating(acceleration, delta_space);
        handle_acceleration_increasing(moved, acceleration);

        /**
         * Toggle Floor.
         */
        if (input_manager->key_press(InputManager::K_C)) {
            is_crossingable = not is_crossingable;
        } else {
            /* Nothing to do. */
        }

        /**
         * Delete floor.
         */
        if (input_manager->is_key_down(InputManager::K_DEL)) {
            is_deleted = true;
        } else {
            /* Nothing to do. */
        }
    } else {
        /* Nothing to do. */
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_platforms_interaction method";
}

/**
 * Handle platform player interaction with the platforms.
 *
 * @param moved will become true if platform move
 * @param delta_space how much platform will move
 */
void EditableFloor::handle_box_moving(bool &moved,
                                      float delta_space) {  // NOLINT
    // LOG(DEBUG) << "Starting EditableFloor handle_box_moving method";

    InputManager *input_manager = InputManager::get_instance();

    if (input_manager->is_key_down(InputManager::K_ARROW_RIGHT)) {
        box.x += delta_space;
        moved = true;
    } else if (input_manager->is_key_down(InputManager::K_ARROW_LEFT)) {
        box.x -= delta_space;
        moved = true;
    } else {
        /* Nothing to do. */
    }

    if (input_manager->is_key_down(InputManager::K_ARROW_UP)) {
        box.y -= delta_space;
        moved = true;
    } else if (input_manager->is_key_down(InputManager::K_ARROW_DOWN)) {
        box.y += delta_space;
        moved = true;
    } else {
        /* Nothing to do. */
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_box_moving method";
}

/**
 * Handle platform player interaction with the platforms.
 *
 * @param moved will become true if platform move
 * @param delta_space how much platform will move
 */
void EditableFloor::handle_box_resizing(bool &moved,
                                        float delta_space) {  // NOLINT
    // LOG(DEBUG) << "Starting EditableFloor handle_box_resizing method";

    /**
     * Limit box sizes.
     */
    if (box.x < 0) {
        box.x = 0;
    } else if (box.x > BACKGROUND_WIDTH) {
        box.x = BACKGROUND_WIDTH;
    } else if (box.y < 0) {
        box.y = 0;
    } else if (box.y > BACKGROUND_HEIGHT) {
        box.y = BACKGROUND_HEIGHT;
    } else {
        /* Nothing to do. */
    }

    InputManager *input_manager = InputManager::get_instance();

    /**
     * Increase floor width.
     */
    if (input_manager->is_key_down(InputManager::K_INC_W)) {
        standard_sprite.update_scale_x(RESIZING_SPEED * delta_space);
        platform_sprite.update_scale_x(RESIZING_SPEED * delta_space);
        selected_sprite.update_scale_x(RESIZING_SPEED * delta_space);

        box.width = standard_sprite.get_width();
        moved = true;
    } else {
        /* Nothing to do. */
    }

    /**
     * Decrease floor width.
     */
    if (input_manager->is_key_down(InputManager::K_DEC_W)) {
        standard_sprite.update_scale_x(-RESIZING_SPEED * delta_space);
        platform_sprite.update_scale_x(-RESIZING_SPEED * delta_space);
        selected_sprite.update_scale_x(-RESIZING_SPEED * delta_space);

        box.width = standard_sprite.get_width();
        moved = true;
    } else {
        /* Nothing to do. */
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_box_resizing method";
}

/**
 * Will handle rotation for both sides and reset.
 *
 * @param acceleration acceleration for rotating platform
 * @param delta_space intensifies rotating speed
 */
void EditableFloor::handle_box_rotating(float acceleration, float delta_space) {
    // LOG(DEBUG) << "Starting EditableFloor handle_box_rotating method";

    InputManager *input_manager = InputManager::get_instance();

    /**
     * Rotate box to corresponding direction or reset it.
     */
    if (input_manager->is_key_down(InputManager::K_ROT_LEFT)) {
        rotation += ROTATING_SPEED * delta_space / acceleration;
    } else if (input_manager->is_key_down(InputManager::K_ROT_RIGHT)) {
        rotation -= ROTATING_SPEED * delta_space / acceleration;
    } else if (input_manager->is_key_down(InputManager::K_ROT_RESET)) {
        rotation = 0;
    } else {
        /* Nothing to do. */
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_box_rotating method";
}

/**
 * Will handle if acceleration increase keeps ou reset
 *
 * @param moved if platform was moved, it will change behavior
 * @param acceleration acceleration that will be changed
 */
void EditableFloor::handle_acceleration_increasing(
    bool &moved,
    float &acceleration) {  // NOLINT
    // LOG(DEBUG) << "Starting EditableFloor handle_acceleration_increasing
    // method";

    if (moved) {
        acceleration = fmin(acceleration + ACCELERATION_INCREASE_STEP,
                            MAXIMUM_ACCELERATION);
    } else {
        acceleration = ACCELERATION;
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_acceleration_increasing
    // method";
}

/**
 * Not implemented.
 *
 * @param unamed An game object.
 */
void EditableFloor::notify_collision(GameObject &) {
}
<commit_msg>Appropriate error handling on EditableFloor<commit_after>/* Copyright (c) 2017 Wenova - Rise of Conquerors. All rights reserved.
 *
 * This work is licensed under the terms of the MIT license.
 * For a copy, see <https://opensource.org/licenses/MIT>.
 */
/**
 * @file EditableFloor.cpp
 * Implements class EditableFloor methods.
 */

/**
 * Commented debugs should be used with extreme care because it causes
 * extremelly lose of performance and giant log files.
 */

#include "EditableFloor.h"

#include "Collision.h"
#include "InputManager.h"
#include "Rectangle.h"

#include <cstdio>

#define BACKGROUND_WIDTH 1280
#define BACKGROUND_HEIGHT 720

#define RESIZING_SPEED 0.005
#define ROTATING_SPEED 0.01
#define MOVE_SPEED 0.5

#define ACCELERATION 1
#define MAXIMUM_ACCELERATION 4
#define ACCELERATION_INCREASE_STEP 0.2

#define RIGID_PLATFORM_PATH "edit_state/floor/editable_floor.png"
#define CROSSINGABLE_PLATFORM_PATH "edit_state/floor/editable_platform.png"
#define SELECTED_CROSSINGABLE_PLATFORM_PATH \
    "edit_state/floor/selected_editable_floor.png"

#define DEBUG_SIZE 500
#define FILL_MISSING_PIXELS_DEBUGRMATIONS 15

#define LAYER 0
#define FLOOR_INITIAL_WIDTH 100
#define PI 3.14159265358979
#define PI_DEGREES 180

/**
 * Create box with default width of 100px.
 *
 * @param x Position in X axis. Unit: px, [0,screen_width]
 * @param y Position in Y axis. Unit: px, [0,screen_height]
 * @param crotation Unit: degrees
 * @param cplatform [0,1]
 */
EditableFloor::EditableFloor(float x, float y, float crotation, bool cplatform)
    : Floor(x, y, FLOOR_INITIAL_WIDTH, crotation, cplatform),
      standard_sprite(Sprite(RIGID_PLATFORM_PATH)),
      platform_sprite(Sprite(CROSSINGABLE_PLATFORM_PATH)),
      selected_sprite(Sprite(SELECTED_CROSSINGABLE_PLATFORM_PATH)) {
#ifndef NDEBUG
    try {
        std::string log_message = "Starting EditableFloor constructor with x: ";
        log_message += std::to_string(x) + ", y: " + std::to_string(y);
        log_message += ", crotation: " + std::to_string(crotation);
        log_message +=
            ", cplatfrom: " + std::to_string(static_cast<int>(cplatform));

        LOG(DEBUG) << log_message;
    } catch (std::bad_alloc &error) {
        string str_error(error.what());
        string log_message = "Couldn't convert to string: " + str_error + '\n';
        LOG(FATAL) << log_message;
    }
#endif

    box = Rectangle(x, y, standard_sprite.get_width(),
                    standard_sprite.get_height());

    is_deleted = false;
    is_selected = false;

    LOG(DEBUG) << "Ending EditableFloor constructor";
}

/**
 * Create box with specific width.
 *
 * @param x Position in X axis. Unit: px, [0,screen_width]
 * @param y Position in Y axis. Unit: px, [0,screen_height]
 * @param width Unit: px, [0,]
 * @param crotation Unit: degrees
 * @param cplatform [0,1]
 */
EditableFloor::EditableFloor(float x, float y, float width, float crotation,
                             bool cplatform)
    : EditableFloor(x, y, crotation, cplatform) {
#ifndef NDEBUG
    try {
        std::string log_message = "Starting EditableFloor constructor with x: ";
        log_message += std::to_string(x) + ", y: " + std::to_string(y);
        log_message += ", width:" + std::to_string(width);
        log_message += ", crotation: " + std::to_string(crotation);
        log_message +=
            ", cplatfrom: " + std::to_string(static_cast<int>(cplatform));
        LOG(DEBUG) << log_message;
    } catch (std::bad_alloc &error) {
        string str_error(error.what());
        string log_message = "Couldn't convert to string: " + str_error + '\n';
        LOG(FATAL) << log_message;
    }

    if (x <= BACKGROUND_WIDTH) {
        /* Nothing to do. */
    } else {
        LOG(FATAL) << "platform is out of screen in axis x";
    }

    if (x <= BACKGROUND_WIDTH) {
        /* Nothing to do. */
    } else {
        LOG(FATAL) << "platform is out of screen in axis y";
    }
#endif

    standard_sprite.set_scale_x(width / standard_sprite.get_width());
    platform_sprite.set_scale_x(width / platform_sprite.get_width());
    selected_sprite.set_scale_x(width / selected_sprite.get_width());

    box.width = standard_sprite.get_width();

    LOG(DEBUG) << "Ending EditableFloor init";
}

/**
 * Not implemented.
 */
EditableFloor::~EditableFloor() {
}

/**
 * Get information about many aspects of an box.
 *
 * @returns String in format: "x y width rotated level is_crossingable?"
 */
string EditableFloor::get_information() {
    LOG(DEBUG) << "Starting EditableFloor get_information";

    char info_c[DEBUG_SIZE];
    int snprint_return = snprintf(
        info_c, sizeof(info_c), "%f %f %f %f %d", box.x, box.y, box.width,
        rotation * PI_DEGREES / PI, static_cast<int>(is_crossingable));

    if (snprint_return == 5) {
        /* Nothing to do. */
    } else {
        LOG(ERROR) << "Could not get the complete information";
    }

    string info(info_c);

    for (auto &c : info) {
        c += FILL_MISSING_PIXELS_DEBUGRMATIONS;
    }

    string return_value = info;

    /*
     * Check if string reallyhas the elements.
     * info == info_c for sure
     */
    float float1, float2, float3, float4;
    int int1;
    if (sscanf(info_c, "%f %f %f %f %d", &float1, &float2, &float3, &float4,
               &int1) == 5) {
        /* Nothing to do. */
    } else {
        LOG(WARNING) << "Info doesn't has all the information it should have";
    }

    std::string log_message =
        "Ending EditableFloor get_information returning value: " + return_value;
    LOG(DEBUG) << log_message;

    return return_value;
}

/**
 * Select elements which will be edited.
 *
 * @param cis_selected [0,1]
 */
void EditableFloor::set_selected(bool cis_selected) {
#ifndef NDEBUG
    std::string log_message =
        "Starting EditableFloor set_selected with cis_selected: " +
        static_cast<int>(cis_selected);
    LOG(DEBUG) << log_message;
#endif

    is_selected = cis_selected;

    LOG(DEBUG) << "Ending EditableFloor set_selected";
}

/**
 * Render selected box considering if it is selected.
 */
void EditableFloor::render() {
    // LOG(DEBUG) << "Starting EditableFloor render";

    if (is_selected) {
        selected_sprite.render(box.get_draw_x(), box.get_draw_y(), rotation);
    } else {
        /* Nothing to do. */
    }

    if (is_crossingable) {
        platform_sprite.render(box.get_draw_x(), box.get_draw_y(), rotation);
    } else {
        standard_sprite.render(box.get_draw_x(), box.get_draw_y(), rotation);
    }

    // LOG(DEBUG) << "Ending EditableFloor render";
}

/**
 * Manages player interaction with the box.
 *
 * @param delta_time Difference in position of the box.
 */
void EditableFloor::update(float delta_time) {
    /*
    #ifndef NDEBUG
    char log_message_c[60];
    snprintf(log_message_c, sizeof(log_message_c), "Starting EditableFloor
    update with delta_time: %.2f", delta_time);

    std::string log_message(log_message_c);
    LOG(DEBUG) << log_message;
    #endif
    */

    handle_platforms_interaction(delta_time);

    // LOG(DEBUG) << "Ending EditableFloor update";
}

/**
 * True if box has been deleted.
 *
 * @returns [0,1]
 */
bool EditableFloor::is_dead() {
    // LOG(DEBUG) << "Starting EditableFloor is_dead";

    bool return_value = is_deleted;

    /*
    #ifndef NDEBUG
    std::string log_message = "Ending EditableFloor is_dead returning value: " +
    std::to_string(static_cast<int>(return_value));
    LOG(DEBUG) << log_message;
    #endif
    */

    return return_value;
}

/**
 * Will handle all interaction of the user with the platform.
 *
 * @param delta_time time spent on each frame of sprites
 */
void EditableFloor::handle_platforms_interaction(float delta_time) {
    // LOG(DEBUG) << "Starting EditableFloor handle_platforms_interaction
    // method";

    InputManager *input_manager = InputManager::get_instance();

    if (input_manager->mouse_press(InputManager::LEFT_MOUSE_BUTTON)) {
        int x = input_manager->get_mouse_x_position();
        int y = input_manager->get_mouse_y_position();

        Rectangle mouse = Rectangle(x, y, 1, 1);
        is_selected = Collision::is_colliding(box, mouse, rotation, 0);
    } else {
        /* Nothing to do. */
    }

    if (is_selected) {
        static float acceleration = ACCELERATION;
        float delta_space = MOVE_SPEED * delta_time * acceleration;
        bool moved = false;

        handle_box_moving(moved, delta_space);
        handle_box_resizing(moved, delta_time);
        handle_box_rotating(acceleration, delta_space);
        handle_acceleration_increasing(moved, acceleration);

        /**
         * Toggle Floor.
         */
        if (input_manager->key_press(InputManager::K_C)) {
            is_crossingable = not is_crossingable;
        } else {
            /* Nothing to do. */
        }

        /**
         * Delete floor.
         */
        if (input_manager->is_key_down(InputManager::K_DEL)) {
            is_deleted = true;
        } else {
            /* Nothing to do. */
        }
    } else {
        /* Nothing to do. */
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_platforms_interaction method";
}

/**
 * Handle platform player interaction with the platforms.
 *
 * @param moved will become true if platform move
 * @param delta_space how much platform will move
 */
void EditableFloor::handle_box_moving(bool &moved, float delta_space) {
    // LOG(DEBUG) << "Starting EditableFloor handle_box_moving method";

    InputManager *input_manager = InputManager::get_instance();

    if (input_manager->is_key_down(InputManager::K_ARROW_RIGHT)) {
        box.x += delta_space;
        moved = true;
    } else if (input_manager->is_key_down(InputManager::K_ARROW_LEFT)) {
        box.x -= delta_space;
        moved = true;
    } else {
        /* Nothing to do. */
    }

    if (input_manager->is_key_down(InputManager::K_ARROW_UP)) {
        box.y -= delta_space;
        moved = true;
    } else if (input_manager->is_key_down(InputManager::K_ARROW_DOWN)) {
        box.y += delta_space;
        moved = true;
    } else {
        /* Nothing to do. */
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_box_moving method";
}

/**
 * Handle platform player interaction with the platforms.
 *
 * @param moved will become true if platform move
 * @param delta_space how much platform will move
 */
void EditableFloor::handle_box_resizing(bool &moved, float delta_space) {
    // LOG(DEBUG) << "Starting EditableFloor handle_box_resizing method";

    /**
     * Limit box sizes.
     */
    if (box.x < 0) {
        box.x = 0;
    } else if (box.x > BACKGROUND_WIDTH) {
        box.x = BACKGROUND_WIDTH;
    } else if (box.y < 0) {
        box.y = 0;
    } else if (box.y > BACKGROUND_HEIGHT) {
        box.y = BACKGROUND_HEIGHT;
    } else {
        /* Nothing to do. */
    }

    InputManager *input_manager = InputManager::get_instance();

    /**
     * Resizing platform.
     */
    if (input_manager->is_key_down(InputManager::K_INC_W)) {
        standard_sprite.update_scale_x(RESIZING_SPEED * delta_space);
        platform_sprite.update_scale_x(RESIZING_SPEED * delta_space);
        selected_sprite.update_scale_x(RESIZING_SPEED * delta_space);

        box.width = standard_sprite.get_width();
        moved = true;
    } else if (input_manager->is_key_down(InputManager::K_DEC_W)) {
        standard_sprite.update_scale_x(-RESIZING_SPEED * delta_space);
        platform_sprite.update_scale_x(-RESIZING_SPEED * delta_space);
        selected_sprite.update_scale_x(-RESIZING_SPEED * delta_space);

        box.width = standard_sprite.get_width();
        moved = true;
    } else {
        /* Nothing to do. */
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_box_resizing method";
}

/**
 * Will handle rotation for both sides and reset.
 *
 * @param acceleration acceleration for rotating platform
 * @param delta_space intensifies rotating speed
 */
void EditableFloor::handle_box_rotating(float acceleration, float delta_space) {
    // LOG(DEBUG) << "Starting EditableFloor handle_box_rotating method";

    InputManager *input_manager = InputManager::get_instance();

    /**
     * Rotate box to corresponding direction or reset it.
     */
    if (input_manager->is_key_down(InputManager::K_ROT_LEFT)) {
        rotation += ROTATING_SPEED * delta_space / acceleration;
    } else if (input_manager->is_key_down(InputManager::K_ROT_RIGHT)) {
        rotation -= ROTATING_SPEED * delta_space / acceleration;
    } else if (input_manager->is_key_down(InputManager::K_ROT_RESET)) {
        rotation = 0;
    } else {
        /* Nothing to do. */
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_box_rotating method";
}

/**
 * Will handle if acceleration increase keeps ou reset
 *
 * @param moved if platform was moved, it will change behavior
 * @param acceleration acceleration that will be changed
 */
void EditableFloor::handle_acceleration_increasing(bool &moved,
                                                   float &acceleration) {
    // LOG(DEBUG) << "Starting EditableFloor handle_acceleration_increasing
    // method";

    if (moved) {
        acceleration = fmin(acceleration + ACCELERATION_INCREASE_STEP,
                            MAXIMUM_ACCELERATION);
    } else {
        acceleration = ACCELERATION;
    }

    // LOG(DEBUG) << "Ending EditableFloor handle_acceleration_increasing
    // method";
}

/**
 * Not implemented.
 *
 * @param unamed An game object.
 */
void EditableFloor::notify_collision(GameObject &) {
}
<|endoftext|>


<commit_before>/*
 * Raging MIDI (https://github.com/waddlesplash/ragingmidi).
 *
 * Copyright (c) 2012-2013 WaddleSplash & contributors (see AUTHORS.txt).
 *
 * 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.
 */

#include "PianoRoll.h"
#include "ui_PianoRoll.h"

#include "MainWind.h"

#ifndef QT_NO_OPENGL
#   include <QGLWidget>
#endif

#include <QMenu>
#include <math.h> // for pow()

#define NOTE_HEIGHT 7

/* Static vars. */
bool PianoRoll::canMoveItems;

/*******************************************************/

PianoRollLine::PianoRollLine(QObject* parent)
    : QObject(parent), QGraphicsRectItem(0)
{
    setBrush(Qt::black);
    setRect(0,0,1,127*NOTE_HEIGHT);
    oldTick = 0;
    p = qobject_cast<QGraphicsView*>(parent);
}

void PianoRollLine::setTick(qint32 tick)
{
    if(tick == oldTick) { return; }
    if(tick-oldTick < 15) { return; }
    oldTick = tick;

    int x = this->x(), y = this->y(),
            w = rect().width(), h = rect().height();

    this->setPos(tick/2.0,0);
    if(!scene()) { return; }
    this->scene()->update(tick/2.0,0,1,scene()->height());

    p->ensureVisible(this,p->viewport()->width()/2,0-scene()->height());

    this->scene()->update(x,y,w,h);
}

/*******************************************************/

PianoRoll::PianoRoll(QWidget *parent) :
    QGraphicsView(parent),
    ui(new Ui::PianoRoll)
{
    ui->setupUi(this);
    darker = QBrush(QColor("#c2e6ff"));
    lighter1 = QBrush(QColor("#eaf6ff"));
    lighter2 = QBrush(QColor("#daffd3"));

    this->setScene(new QGraphicsScene(this));
    this->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    tools = new QActionGroup(this);
    tools->addAction(ui->actionNavigationTool);
    tools->addAction(ui->actionMoveTool);

    connect(MainWind::settings,SIGNAL(somethingChanged(QString)),this,SLOT(handleChange(QString)));
#ifndef QT_NO_OPENGL
    if(MainWind::settings->getHWA()) { this->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); }
#endif

    file = 0;
    line = 0;
    canMoveItems = false;
}

PianoRoll::~PianoRoll()
{
    delete ui;
}

void PianoRoll::handleChange(QString a)
{
#ifndef QT_NO_OPENGL
    if(a == "HWA") {
        if(MainWind::settings->getHWA()) { this->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); }
        else { this->setViewport(new QWidget()); }
    }
#endif
}

void PianoRoll::handleNoteChange()
{
    emit somethingChanged();
}

PianoRollLine* PianoRoll::initLine(qint32 tick)
{
    line = new PianoRollLine(this);
    line->setTick(tick);
    scene()->addItem((QGraphicsItem*)line);
    return line;
}

void PianoRoll::deleteLine()
{
    scene()->removeItem((QGraphicsItem*)line);
    delete line;
    line = 0;
}

void PianoRoll::initEditor(QMidiFile* f)
{
    scene()->clear();
    file = f;
    PianoRollEvent* edEv = 0;
    QMidiEvent* noteOn = 0;

    QMap<int,QMidiEvent*> lastNoteOn;

    QList<QMidiEvent*>* events = file->events();
    for(int i = 0;i<events->count(); i++) {
        QMidiEvent* e = events->at(i);
        if(e->isNoteEvent()) {
            if(e->type() == QMidiEvent::NoteOff) {
                noteOn = lastNoteOn.value(e->note(),0);
                if(!noteOn) { continue; }
                edEv = new PianoRollEvent();
                edEv->setColor(MainWind::trackColors->value(e->track()));
                connect(edEv,SIGNAL(somethingChanged()),
                        this,SLOT(handleNoteChange()));

                qreal y = (127 - e->note())*NOTE_HEIGHT;
                qreal w = (e->tick() - noteOn->tick())/2.0;
                edEv->setSize(noteOn->tick()/2.0,y,w,NOTE_HEIGHT);
                edEv->setNoteOnAndOff(noteOn,e);
                scene()->addItem((QGraphicsItem*)edEv);

                lastNoteOn.remove(e->note());
            }
            else
            { lastNoteOn.insert(e->note(),e); }
        }
    }
    this->setSceneRect(QRect());
}
void PianoRoll::wheelEvent(QWheelEvent* e)
{
    // http://www.qtcentre.org/threads/35738#post174006
    if(e->modifiers().testFlag(Qt::ControlModifier)) {
        int numSteps = e->delta() / 15 / 8;

        if(numSteps == 0) {
            e->ignore();
            return;
        }
        qreal sc = pow(1.25, numSteps);
        zoom(sc, mapToScene(e->pos()));
        e->accept();
    }
    else
    { QGraphicsView::wheelEvent(e); }
}

void PianoRoll::zoom(qreal factor, QPointF centerPoint)
{
    scale(factor, factor);
    centerOn(centerPoint);
}

void PianoRoll::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu m(this);
    m.addAction(tr("Zoom 100%"));
    QAction* a = m.exec(mapToGlobal(event->pos()));
    if(!a) { return; }
    if(a->text() == tr("Zoom 100%"))
    { this->resetTransform(); }
}

static int pianoKeyColor[12] = {
    0 /* white */, 1 /* black */, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0
};

void PianoRoll::drawBackground(QPainter *painter, const QRectF &rect)
{
    qreal width = this->scene()->width();

    painter->setClipRect(rect);
    painter->setPen(Qt::NoPen);
    for(int i = 0; i < 128; i++) {
        if(i == 60) { // Middle C
            painter->setBrush(QBrush(QColor("#80ff80")));
        } else {
            int octave = (i - 5) / 12;
            painter->setBrush(pianoKeyColor[i % 12] ? darker : ((octave % 2) ? lighter1 : lighter2));
        }
        painter->drawRect(QRectF(0,i*NOTE_HEIGHT,width,NOTE_HEIGHT));
    }
}

void PianoRoll::on_actionMoveTool_toggled(bool v)
{
    canMoveItems = v;
}

/*******************************************************/

PianoRollEvent::PianoRollEvent(QObject *p)
    : QObject(p), QGraphicsRectItem(0)
{
    setFlag(QGraphicsItem::ItemIsFocusable);
    setFlag(QGraphicsItem::ItemIsSelectable);
    setFlag(QGraphicsItem::ItemIsMovable);
}
void PianoRollEvent::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
    if(PianoRoll::canMoveItems) {
        QGraphicsRectItem::mousePressEvent(e);
    }
}
void PianoRollEvent::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
{
    if(PianoRoll::canMoveItems) {
        QGraphicsRectItem::mouseMoveEvent(e);
    }
}
void PianoRollEvent::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
{
    if(!PianoRoll::canMoveItems) { return; }
    QGraphicsRectItem::mouseReleaseEvent(e);

    int note = 127-(y()/NOTE_HEIGHT);
    qint32 tick = x()*2;
    qint32 dur = myNoteOff->tick()-myNoteOn->tick();
    if(tick == myNoteOn->tick()) { return; }
    else { emit somethingChanged(); }

    if(note > 127) { note = 127; }
    if(note < 0) { note = 0; }
    if(tick < 0) { tick = 0; }
    setY((127-note)*NOTE_HEIGHT);
    setX(tick/2.0);

    myNoteOn->setNote(note);
    myNoteOn->setTick(tick);
    myNoteOff->setNote(note);
    myNoteOff->setTick(tick+dur);
}
void PianoRollEvent::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->setBrush(myColor);
    if(this->rect().width() > 3)
    { painter->drawRoundedRect(rect(),3,3); }
    else { painter->drawRoundedRect(rect(),1,1); }
}
<commit_msg>Increase note height to 9px.<commit_after>/*
 * Raging MIDI (https://github.com/waddlesplash/ragingmidi).
 *
 * Copyright (c) 2012-2013 WaddleSplash & contributors (see AUTHORS.txt).
 *
 * 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.
 */

#include "PianoRoll.h"
#include "ui_PianoRoll.h"

#include "MainWind.h"

#ifndef QT_NO_OPENGL
#   include <QGLWidget>
#endif

#include <QMenu>
#include <math.h> // for pow()

#define NOTE_HEIGHT 9 /* pixels */

/* Static vars. */
bool PianoRoll::canMoveItems;

/*******************************************************/

PianoRollLine::PianoRollLine(QObject* parent)
    : QObject(parent), QGraphicsRectItem(0)
{
    setBrush(Qt::black);
    setRect(0,0,1,127*NOTE_HEIGHT);
    oldTick = 0;
    p = qobject_cast<QGraphicsView*>(parent);
}

void PianoRollLine::setTick(qint32 tick)
{
    if(tick == oldTick) { return; }
    if(tick-oldTick < 15) { return; }
    oldTick = tick;

    int x = this->x(), y = this->y(),
            w = rect().width(), h = rect().height();

    this->setPos(tick/2.0,0);
    if(!scene()) { return; }
    this->scene()->update(tick/2.0,0,1,scene()->height());

    p->ensureVisible(this,p->viewport()->width()/2,0-scene()->height());

    this->scene()->update(x,y,w,h);
}

/*******************************************************/

PianoRoll::PianoRoll(QWidget *parent) :
    QGraphicsView(parent),
    ui(new Ui::PianoRoll)
{
    ui->setupUi(this);
    darker = QBrush(QColor("#c2e6ff"));
    lighter1 = QBrush(QColor("#eaf6ff"));
    lighter2 = QBrush(QColor("#daffd3"));

    this->setScene(new QGraphicsScene(this));
    this->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    tools = new QActionGroup(this);
    tools->addAction(ui->actionNavigationTool);
    tools->addAction(ui->actionMoveTool);

    connect(MainWind::settings,SIGNAL(somethingChanged(QString)),this,SLOT(handleChange(QString)));
#ifndef QT_NO_OPENGL
    if(MainWind::settings->getHWA()) { this->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); }
#endif

    file = 0;
    line = 0;
    canMoveItems = false;
}

PianoRoll::~PianoRoll()
{
    delete ui;
}

void PianoRoll::handleChange(QString a)
{
#ifndef QT_NO_OPENGL
    if(a == "HWA") {
        if(MainWind::settings->getHWA()) { this->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); }
        else { this->setViewport(new QWidget()); }
    }
#endif
}

void PianoRoll::handleNoteChange()
{
    emit somethingChanged();
}

PianoRollLine* PianoRoll::initLine(qint32 tick)
{
    line = new PianoRollLine(this);
    line->setTick(tick);
    scene()->addItem((QGraphicsItem*)line);
    return line;
}

void PianoRoll::deleteLine()
{
    scene()->removeItem((QGraphicsItem*)line);
    delete line;
    line = 0;
}

void PianoRoll::initEditor(QMidiFile* f)
{
    scene()->clear();
    file = f;
    PianoRollEvent* edEv = 0;
    QMidiEvent* noteOn = 0;

    QMap<int,QMidiEvent*> lastNoteOn;

    QList<QMidiEvent*>* events = file->events();
    for(int i = 0;i<events->count(); i++) {
        QMidiEvent* e = events->at(i);
        if(e->isNoteEvent()) {
            if(e->type() == QMidiEvent::NoteOff) {
                noteOn = lastNoteOn.value(e->note(),0);
                if(!noteOn) { continue; }
                edEv = new PianoRollEvent();
                edEv->setColor(MainWind::trackColors->value(e->track()));
                connect(edEv,SIGNAL(somethingChanged()),
                        this,SLOT(handleNoteChange()));

                qreal y = (127 - e->note())*NOTE_HEIGHT;
                qreal w = (e->tick() - noteOn->tick())/2.0;
                edEv->setSize(noteOn->tick()/2.0,y,w,NOTE_HEIGHT);
                edEv->setNoteOnAndOff(noteOn,e);
                scene()->addItem((QGraphicsItem*)edEv);

                lastNoteOn.remove(e->note());
            }
            else
            { lastNoteOn.insert(e->note(),e); }
        }
    }
    this->setSceneRect(QRect());
}
void PianoRoll::wheelEvent(QWheelEvent* e)
{
    // http://www.qtcentre.org/threads/35738#post174006
    if(e->modifiers().testFlag(Qt::ControlModifier)) {
        int numSteps = e->delta() / 15 / 8;

        if(numSteps == 0) {
            e->ignore();
            return;
        }
        qreal sc = pow(1.25, numSteps);
        zoom(sc, mapToScene(e->pos()));
        e->accept();
    }
    else
    { QGraphicsView::wheelEvent(e); }
}

void PianoRoll::zoom(qreal factor, QPointF centerPoint)
{
    scale(factor, factor);
    centerOn(centerPoint);
}

void PianoRoll::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu m(this);
    m.addAction(tr("Zoom 100%"));
    QAction* a = m.exec(mapToGlobal(event->pos()));
    if(!a) { return; }
    if(a->text() == tr("Zoom 100%"))
    { this->resetTransform(); }
}

static int pianoKeyColor[12] = {
    0 /* white */, 1 /* black */, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0
};

void PianoRoll::drawBackground(QPainter *painter, const QRectF &rect)
{
    qreal width = this->scene()->width();

    painter->setClipRect(rect);
    painter->setPen(Qt::NoPen);
    for(int i = 0; i < 128; i++) {
        if(i == 60) { // Middle C
            painter->setBrush(QBrush(QColor("#80ff80")));
        } else {
            int octave = (i - 5) / 12;
            painter->setBrush(pianoKeyColor[i % 12] ? darker : ((octave % 2) ? lighter1 : lighter2));
        }
        painter->drawRect(QRectF(0,i*NOTE_HEIGHT,width,NOTE_HEIGHT));
    }
}

void PianoRoll::on_actionMoveTool_toggled(bool v)
{
    canMoveItems = v;
}

/*******************************************************/

PianoRollEvent::PianoRollEvent(QObject *p)
    : QObject(p), QGraphicsRectItem(0)
{
    setFlag(QGraphicsItem::ItemIsFocusable);
    setFlag(QGraphicsItem::ItemIsSelectable);
    setFlag(QGraphicsItem::ItemIsMovable);
}
void PianoRollEvent::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
    if(PianoRoll::canMoveItems) {
        QGraphicsRectItem::mousePressEvent(e);
    }
}
void PianoRollEvent::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
{
    if(PianoRoll::canMoveItems) {
        QGraphicsRectItem::mouseMoveEvent(e);
    }
}
void PianoRollEvent::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
{
    if(!PianoRoll::canMoveItems) { return; }
    QGraphicsRectItem::mouseReleaseEvent(e);

    int note = 127-(y()/NOTE_HEIGHT);
    qint32 tick = x()*2;
    qint32 dur = myNoteOff->tick()-myNoteOn->tick();
    if(tick == myNoteOn->tick()) { return; }
    else { emit somethingChanged(); }

    if(note > 127) { note = 127; }
    if(note < 0) { note = 0; }
    if(tick < 0) { tick = 0; }
    setY((127-note)*NOTE_HEIGHT);
    setX(tick/2.0);

    myNoteOn->setNote(note);
    myNoteOn->setTick(tick);
    myNoteOff->setNote(note);
    myNoteOff->setTick(tick+dur);
}
void PianoRollEvent::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->setBrush(myColor);
    if(this->rect().width() > 3)
    { painter->drawRoundedRect(rect(),3,3); }
    else { painter->drawRoundedRect(rect(),1,1); }
}
<|endoftext|>


<commit_before>/**
 *
 * @file compiled_plugin_base.cpp
 *
 * @date Jan 15, 2013
 * @author partio
 */

#include "compiled_plugin_base.h"
#include <boost/thread.hpp>
#include "plugin_factory.h"
#include "logger_factory.h"

#define HIMAN_AUXILIARY_INCLUDE

#include "neons.h"
#include "writer.h"
#include "pcuda.h"
#include "cache.h"

#undef HIMAN_AUXILIARY_INCLUDE

using namespace std;
using namespace himan::plugin;

const double kInterpolatedValueEpsilon = 0.00001; //<! Max difference between two grid points (if smaller, points are considered the same)
mutex itsAdjustDimensionMutex;

compiled_plugin_base::compiled_plugin_base() : itsPluginIsInitialized(false)
{
	itsBaseLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("compiled_plugin_base"));
}

bool compiled_plugin_base::InterpolateToPoint(shared_ptr<const NFmiGrid> targetGrid, shared_ptr<NFmiGrid> sourceGrid, bool gridsAreEqual, double& value)
{

	/*
	 * Logic of interpolating values:
	 *
	 * 1) If source and target grids are equal, meaning that the grid AND the area
	 *	properties are effectively the same, do not interpolate. Instead return
	 *	the value of the source grid point that matches the ordering number of the
	 *	target grid point (ie. target grid point #1 --> source grid point #1 etc).
	 *
	 * 2) If actual interpolation is needed, first get the *grid* coordinates of the
	 *	latlon target point in the *source* grid. Then check if those grid coordinates
	 *  are very close to an actual grid point -- if so, return the value of the grid
	 *  point. This serves two purposes:
	 *	- We don't need to interpolate if the distance between requested grid point
	 *	  and actual grid point is small enough, saving some CPU cycles
	 *	- Sometimes when the requested grid point is close to grid edge, floating
	 *	  point inaccuracies might move it outside the grid. If this happens, the
	 *	  interpolation fails even though the grid point is valid.
	 *
	 * 3) If requested source grid point is not near an actual grid point, interpolate
	 *	the value of the point.
	 */

	// Step 1)

	if (gridsAreEqual)
	{
		value = sourceGrid->FloatValue(targetGrid->GridPoint());
		return true;
	}

	// Step 2)

	const NFmiPoint targetLatLonPoint = targetGrid->LatLon();
	const NFmiPoint sourceGridPoint = sourceGrid->LatLonToGrid(targetLatLonPoint);

	bool noInterpolation = (
						fabs(sourceGridPoint.X() - round(sourceGridPoint.X())) < kInterpolatedValueEpsilon &&
						fabs(sourceGridPoint.Y() - round(sourceGridPoint.Y())) < kInterpolatedValueEpsilon
	);

	if (noInterpolation)
	{
		value = sourceGrid->FloatValue(sourceGridPoint);
		return true;
	}

	// Step 3)

	return sourceGrid->InterpolateToGridPoint(sourceGridPoint, value);

}

bool compiled_plugin_base::AdjustLeadingDimension(shared_ptr<info> myTargetInfo)
{

	lock_guard<mutex> lock(itsAdjustDimensionMutex);

	// Leading dimension can be: time or level

	if (itsLeadingDimension == kTimeDimension)
	{
		if (!itsInfo->NextTime())
		{
			return false;
		}

		myTargetInfo->Time(itsInfo->Time());
	}
	else if (itsLeadingDimension == kLevelDimension)
	{
		if (!itsInfo->NextLevel())
		{
			return false;
		}

		myTargetInfo->Level(itsInfo->Level());
	}
	else
	{
		throw runtime_error(ClassName() + ": Invalid dimension type: " + boost::lexical_cast<string> (itsLeadingDimension));
	}

	return true;
}

bool compiled_plugin_base::AdjustNonLeadingDimension(shared_ptr<info> myTargetInfo)
{
	if (itsLeadingDimension == kTimeDimension)
	{
		return myTargetInfo->NextLevel();
	}
	else if (itsLeadingDimension == kLevelDimension)
	{
		return myTargetInfo->NextTime();
	}
	else
	{
		throw runtime_error(ClassName() + ": unsupported leading dimension: " + boost::lexical_cast<string> (itsLeadingDimension));
	}
}

void compiled_plugin_base::ResetNonLeadingDimension(shared_ptr<info> myTargetInfo)
{
	if (itsLeadingDimension == kTimeDimension)
	{
		myTargetInfo->ResetLevel();
	}
	else if (itsLeadingDimension == kLevelDimension)
	{
		myTargetInfo->ResetTime();
	}
	else
	{
		throw runtime_error(ClassName() + ": unsupported leading dimension: " + boost::lexical_cast<string> (itsLeadingDimension));
	}
}

bool compiled_plugin_base::SetAB(shared_ptr<info> myTargetInfo, shared_ptr<info> sourceInfo)
{
	if (myTargetInfo->Level().Type() == kHybrid)
	{
		size_t index = myTargetInfo->ParamIndex();

		myTargetInfo->Grid()->AB(sourceInfo->Grid()->AB());

		myTargetInfo->ParamIndex(index);
	}

	return true;
}

bool compiled_plugin_base::SwapTo(shared_ptr<info> myTargetInfo, HPScanningMode targetScanningMode)
{

	if (myTargetInfo->Grid()->ScanningMode() != targetScanningMode)
	{
		HPScanningMode originalMode = myTargetInfo->Grid()->ScanningMode();

		myTargetInfo->Grid()->ScanningMode(targetScanningMode);

		myTargetInfo->Grid()->Swap(originalMode);
	}

	return true;
}

void compiled_plugin_base::WriteToFile(shared_ptr<const info> targetInfo)
{
	shared_ptr<writer> aWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

	// writing might modify iterator positions --> create a copy

	auto tempInfo = make_shared<info> (*targetInfo);

	if (itsConfiguration->FileWriteOption() == kNeons || itsConfiguration->FileWriteOption() == kMultipleFiles)
	{
		// If info holds multiple parameters, we must loop over them all
		// Note! We only loop over the parameters, not over the times or levels!

		tempInfo->ResetParam();

		while (tempInfo->NextParam())
		{
			aWriter->ToFile(tempInfo, itsConfiguration);
		}
	}
	else if (itsConfiguration->FileWriteOption() == kSingleFile)
	{
		aWriter->ToFile(tempInfo, itsConfiguration, itsConfiguration->ConfigurationFile());
	}
}

bool compiled_plugin_base::GetAndSetCuda(shared_ptr<const configuration> conf, int threadIndex)
{
#ifdef HAVE_CUDA
	bool ret = conf->UseCuda() && conf->CudaDeviceId() < conf->CudaDeviceCount();

	if (ret)
	{
		shared_ptr<pcuda> p = dynamic_pointer_cast <pcuda> (plugin_factory::Instance()->Plugin("pcuda"));

		ret = p->SetDevice(conf->CudaDeviceId());
	}
#else
	bool ret = false;
#endif

	return ret;
}

void compiled_plugin_base::ResetCuda() const
{
#ifdef HAVE_CUDA
	shared_ptr<pcuda> p = dynamic_pointer_cast <pcuda> (plugin_factory::Instance()->Plugin("pcuda"));
	p->Reset();
#endif
}

void compiled_plugin_base::Start()
{
	if (!itsPluginIsInitialized)
	{
		itsBaseLogger->Error("Start() called before Init()");
		return;
	}

	boost::thread_group g;

	/*
	 * Each thread will have a copy of the target info.
	 */

	for (short i = 0; i < itsThreadCount; i++)
	{

		printf("Info::compiled_plugin: Thread %d starting\n", (i + 1)); // Printf is thread safe

		boost::thread* t = new boost::thread(&compiled_plugin_base::Run,
											 this,
											 make_shared<info> (*itsInfo),
											 i + 1);

		g.add_thread(t);

	}

	g.join_all();

	Finish();
}

void compiled_plugin_base::Init(shared_ptr<const plugin_configuration> conf)
{

	const short MAX_THREADS = 12; //<! Max number of threads we allow

	itsConfiguration = conf;

	if (itsConfiguration->StatisticsEnabled())
	{
		itsTimer = unique_ptr<timer> (timer_factory::Instance()->GetTimer());
		itsTimer->Start();
		itsConfiguration->Statistics()->UsedGPUCount(conf->CudaDeviceCount());
	}

	// Determine thread count

	short coreCount = static_cast<short> (boost::thread::hardware_concurrency()); // Number of cores

	itsThreadCount = MAX_THREADS;

	// If user has specified thread count, always use that
	if (conf->ThreadCount() > 0)
	{
		itsThreadCount = conf->ThreadCount();
	}
	// we don't want to use all cores in a server by default
	else if (MAX_THREADS > coreCount)
	{
		itsThreadCount = coreCount;
	}

	itsInfo = itsConfiguration->Info();

	itsLeadingDimension = itsConfiguration->LeadingDimension();

	itsPluginIsInitialized = true;
}

void compiled_plugin_base::Run(shared_ptr<info> myTargetInfo, unsigned short threadIndex)
{
	while (AdjustLeadingDimension(myTargetInfo))
	{
		Calculate(myTargetInfo, threadIndex);
	}
}

void compiled_plugin_base::Finish()
{

	if (itsConfiguration->StatisticsEnabled())
	{
		itsTimer->Stop();
		itsConfiguration->Statistics()->AddToProcessingTime(itsTimer->GetTime());
	}

	if (itsConfiguration->FileWriteOption() == kSingleFile)
	{
		WriteToFile(itsInfo);
	}
}

void compiled_plugin_base::Calculate(std::shared_ptr<info> myTargetInfo, unsigned short threadIndex)
{
	itsBaseLogger->Fatal("Top level calculate called");
	exit(1);
}

void compiled_plugin_base::SetParams(std::vector<param>& params)
{
	if (params.empty())
	{
		itsBaseLogger->Fatal("size of target parameter vector is zero");
		exit(1);
	}

	// GRIB 1

	if (itsConfiguration->OutputFileType() == kGRIB1)
	{
		auto n = dynamic_pointer_cast<plugin::neons> (plugin_factory::Instance()->Plugin("neons"));

		for (unsigned int i = 0; i < params.size(); i++)
		{
			long table2Version = itsInfo->Producer().TableVersion();
			long parm_id = n->NeonsDB().GetGridParameterId(table2Version, params[i].Name());

			if (parm_id == -1)
			{
				itsBaseLogger->Warning("Grib1 parameter definitions not found from Neons");
				itsBaseLogger->Warning("table2Version is " + boost::lexical_cast<string> (table2Version) + ", parm_name is " + params[i].Name());
			}

			params[i].GribIndicatorOfParameter(parm_id);
			params[i].GribTableVersion(table2Version);
		}
	}

	itsInfo->Params(params);

	/*
	 * Create data structures.
	 */

	itsInfo->Create();

	/*
	 * Iterators must be reseted since they are at first position after Create()
	 */

	itsInfo->Reset();

	/*
	 * Do not launch more threads than there are things to calculate.
	 */

	if (itsLeadingDimension == kTimeDimension)
	{
		if (itsInfo->SizeTimes() < static_cast<size_t> (itsThreadCount))
		{
			itsThreadCount = static_cast<short> (itsInfo->SizeTimes());
		}
	}
	else if (itsLeadingDimension == kLevelDimension)
	{
		if (itsInfo->SizeLevels() < static_cast<size_t> (itsThreadCount))
		{
			itsThreadCount = static_cast<short> (itsInfo->SizeLevels());
		}
	}

	/*
	 * From the timing perspective at this point plugin initialization is
	 * considered to be done
	 */

	if (itsConfiguration->StatisticsEnabled())
	{
		itsConfiguration->Statistics()->UsedThreadCount(itsThreadCount);
		itsTimer->Stop();
		itsConfiguration->Statistics()->AddToInitTime(itsTimer->GetTime());
		itsTimer->Start();
	}
}

#ifdef HAVE_CUDA
void compiled_plugin_base::Unpack(initializer_list<shared_ptr<info>> infos)
{
	auto c = dynamic_pointer_cast<plugin::cache> (plugin_factory::Instance()->Plugin("cache"));

	for (auto it = infos.begin(); it != infos.end(); ++it)
	{
		shared_ptr<info> tempInfo = *it;

		if (!tempInfo->Grid()->PackedData() || tempInfo->Grid()->PackedData()->packedLength == 0)
		{
			// Safeguard: This particular info does not have packed data
			continue;
		}

		assert(tempInfo->Grid()->PackedData()->ClassName() == "simple_packed");

		double* arr;
		size_t N = tempInfo->Grid()->PackedData()->unpackedLength;

		assert(N);

		CUDA_CHECK(cudaMallocHost(reinterpret_cast<void**> (&arr), sizeof(double) * N));

		dynamic_pointer_cast<simple_packed> (tempInfo->Grid()->PackedData())->Unpack(arr, N);

		tempInfo->Data()->Set(arr, N);

		CUDA_CHECK(cudaFreeHost(arr));

		tempInfo->Grid()->PackedData()->Clear();

		if (itsConfiguration->UseCache())
		{
			c->Insert(tempInfo);
		}
	}
}

void compiled_plugin_base::CopyDataFromSimpleInfo(shared_ptr<info> anInfo, info_simple* aSimpleInfo, bool writeToCache)
{
	assert(aSimpleInfo);

	anInfo->Data()->Set(aSimpleInfo->values, aSimpleInfo->size_x * aSimpleInfo->size_y);

	if (anInfo->Grid()->IsPackedData())
	{
		anInfo->Grid()->PackedData()->Clear();
	}

	aSimpleInfo->free_values();

	if (writeToCache && itsConfiguration->UseCache())
	{
		auto c = dynamic_pointer_cast<plugin::cache> (plugin_factory::Instance()->Plugin("cache"));
		c->Insert(anInfo);
	}
}
#endif

bool compiled_plugin_base::CompareGrids(initializer_list<shared_ptr<grid>> grids)
{
	if (grids.size() <= 1)
	{
		throw kUnknownException;
	}

	auto it = grids.begin();
	auto first = *it;

	for (++it; it != grids.end(); ++it)
	{
		if (*first != **it)
		{
			return false;
		}
	}

	return true;
}

bool compiled_plugin_base::IsMissingValue(initializer_list<double> values)
{
	for (auto it = values.begin(); it != values.end(); ++it)
	{
		if (*it == kFloatMissing)
		{
			return true;
		}
	}

	return false;
}<commit_msg>Skip null pointers<commit_after>/**
 *
 * @file compiled_plugin_base.cpp
 *
 * @date Jan 15, 2013
 * @author partio
 */

#include "compiled_plugin_base.h"
#include <boost/thread.hpp>
#include "plugin_factory.h"
#include "logger_factory.h"

#define HIMAN_AUXILIARY_INCLUDE

#include "neons.h"
#include "writer.h"
#include "pcuda.h"
#include "cache.h"

#undef HIMAN_AUXILIARY_INCLUDE

using namespace std;
using namespace himan::plugin;

const double kInterpolatedValueEpsilon = 0.00001; //<! Max difference between two grid points (if smaller, points are considered the same)
mutex itsAdjustDimensionMutex;

compiled_plugin_base::compiled_plugin_base() : itsPluginIsInitialized(false)
{
	itsBaseLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("compiled_plugin_base"));
}

bool compiled_plugin_base::InterpolateToPoint(shared_ptr<const NFmiGrid> targetGrid, shared_ptr<NFmiGrid> sourceGrid, bool gridsAreEqual, double& value)
{

	/*
	 * Logic of interpolating values:
	 *
	 * 1) If source and target grids are equal, meaning that the grid AND the area
	 *	properties are effectively the same, do not interpolate. Instead return
	 *	the value of the source grid point that matches the ordering number of the
	 *	target grid point (ie. target grid point #1 --> source grid point #1 etc).
	 *
	 * 2) If actual interpolation is needed, first get the *grid* coordinates of the
	 *	latlon target point in the *source* grid. Then check if those grid coordinates
	 *  are very close to an actual grid point -- if so, return the value of the grid
	 *  point. This serves two purposes:
	 *	- We don't need to interpolate if the distance between requested grid point
	 *	  and actual grid point is small enough, saving some CPU cycles
	 *	- Sometimes when the requested grid point is close to grid edge, floating
	 *	  point inaccuracies might move it outside the grid. If this happens, the
	 *	  interpolation fails even though the grid point is valid.
	 *
	 * 3) If requested source grid point is not near an actual grid point, interpolate
	 *	the value of the point.
	 */

	// Step 1)

	if (gridsAreEqual)
	{
		value = sourceGrid->FloatValue(targetGrid->GridPoint());
		return true;
	}

	// Step 2)

	const NFmiPoint targetLatLonPoint = targetGrid->LatLon();
	const NFmiPoint sourceGridPoint = sourceGrid->LatLonToGrid(targetLatLonPoint);

	bool noInterpolation = (
						fabs(sourceGridPoint.X() - round(sourceGridPoint.X())) < kInterpolatedValueEpsilon &&
						fabs(sourceGridPoint.Y() - round(sourceGridPoint.Y())) < kInterpolatedValueEpsilon
	);

	if (noInterpolation)
	{
		value = sourceGrid->FloatValue(sourceGridPoint);
		return true;
	}

	// Step 3)

	return sourceGrid->InterpolateToGridPoint(sourceGridPoint, value);

}

bool compiled_plugin_base::AdjustLeadingDimension(shared_ptr<info> myTargetInfo)
{

	lock_guard<mutex> lock(itsAdjustDimensionMutex);

	// Leading dimension can be: time or level

	if (itsLeadingDimension == kTimeDimension)
	{
		if (!itsInfo->NextTime())
		{
			return false;
		}

		myTargetInfo->Time(itsInfo->Time());
	}
	else if (itsLeadingDimension == kLevelDimension)
	{
		if (!itsInfo->NextLevel())
		{
			return false;
		}

		myTargetInfo->Level(itsInfo->Level());
	}
	else
	{
		throw runtime_error(ClassName() + ": Invalid dimension type: " + boost::lexical_cast<string> (itsLeadingDimension));
	}

	return true;
}

bool compiled_plugin_base::AdjustNonLeadingDimension(shared_ptr<info> myTargetInfo)
{
	if (itsLeadingDimension == kTimeDimension)
	{
		return myTargetInfo->NextLevel();
	}
	else if (itsLeadingDimension == kLevelDimension)
	{
		return myTargetInfo->NextTime();
	}
	else
	{
		throw runtime_error(ClassName() + ": unsupported leading dimension: " + boost::lexical_cast<string> (itsLeadingDimension));
	}
}

void compiled_plugin_base::ResetNonLeadingDimension(shared_ptr<info> myTargetInfo)
{
	if (itsLeadingDimension == kTimeDimension)
	{
		myTargetInfo->ResetLevel();
	}
	else if (itsLeadingDimension == kLevelDimension)
	{
		myTargetInfo->ResetTime();
	}
	else
	{
		throw runtime_error(ClassName() + ": unsupported leading dimension: " + boost::lexical_cast<string> (itsLeadingDimension));
	}
}

bool compiled_plugin_base::SetAB(shared_ptr<info> myTargetInfo, shared_ptr<info> sourceInfo)
{
	if (myTargetInfo->Level().Type() == kHybrid)
	{
		size_t index = myTargetInfo->ParamIndex();

		myTargetInfo->Grid()->AB(sourceInfo->Grid()->AB());

		myTargetInfo->ParamIndex(index);
	}

	return true;
}

bool compiled_plugin_base::SwapTo(shared_ptr<info> myTargetInfo, HPScanningMode targetScanningMode)
{

	if (myTargetInfo->Grid()->ScanningMode() != targetScanningMode)
	{
		HPScanningMode originalMode = myTargetInfo->Grid()->ScanningMode();

		myTargetInfo->Grid()->ScanningMode(targetScanningMode);

		myTargetInfo->Grid()->Swap(originalMode);
	}

	return true;
}

void compiled_plugin_base::WriteToFile(shared_ptr<const info> targetInfo)
{
	shared_ptr<writer> aWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

	// writing might modify iterator positions --> create a copy

	auto tempInfo = make_shared<info> (*targetInfo);

	if (itsConfiguration->FileWriteOption() == kNeons || itsConfiguration->FileWriteOption() == kMultipleFiles)
	{
		// If info holds multiple parameters, we must loop over them all
		// Note! We only loop over the parameters, not over the times or levels!

		tempInfo->ResetParam();

		while (tempInfo->NextParam())
		{
			aWriter->ToFile(tempInfo, itsConfiguration);
		}
	}
	else if (itsConfiguration->FileWriteOption() == kSingleFile)
	{
		aWriter->ToFile(tempInfo, itsConfiguration, itsConfiguration->ConfigurationFile());
	}
}

bool compiled_plugin_base::GetAndSetCuda(shared_ptr<const configuration> conf, int threadIndex)
{
#ifdef HAVE_CUDA
	bool ret = conf->UseCuda() && conf->CudaDeviceId() < conf->CudaDeviceCount();

	if (ret)
	{
		shared_ptr<pcuda> p = dynamic_pointer_cast <pcuda> (plugin_factory::Instance()->Plugin("pcuda"));

		ret = p->SetDevice(conf->CudaDeviceId());
	}
#else
	bool ret = false;
#endif

	return ret;
}

void compiled_plugin_base::ResetCuda() const
{
#ifdef HAVE_CUDA
	shared_ptr<pcuda> p = dynamic_pointer_cast <pcuda> (plugin_factory::Instance()->Plugin("pcuda"));
	p->Reset();
#endif
}

void compiled_plugin_base::Start()
{
	if (!itsPluginIsInitialized)
	{
		itsBaseLogger->Error("Start() called before Init()");
		return;
	}

	boost::thread_group g;

	/*
	 * Each thread will have a copy of the target info.
	 */

	for (short i = 0; i < itsThreadCount; i++)
	{

		printf("Info::compiled_plugin: Thread %d starting\n", (i + 1)); // Printf is thread safe

		boost::thread* t = new boost::thread(&compiled_plugin_base::Run,
											 this,
											 make_shared<info> (*itsInfo),
											 i + 1);

		g.add_thread(t);

	}

	g.join_all();

	Finish();
}

void compiled_plugin_base::Init(shared_ptr<const plugin_configuration> conf)
{

	const short MAX_THREADS = 12; //<! Max number of threads we allow

	itsConfiguration = conf;

	if (itsConfiguration->StatisticsEnabled())
	{
		itsTimer = unique_ptr<timer> (timer_factory::Instance()->GetTimer());
		itsTimer->Start();
		itsConfiguration->Statistics()->UsedGPUCount(conf->CudaDeviceCount());
	}

	// Determine thread count

	short coreCount = static_cast<short> (boost::thread::hardware_concurrency()); // Number of cores

	itsThreadCount = MAX_THREADS;

	// If user has specified thread count, always use that
	if (conf->ThreadCount() > 0)
	{
		itsThreadCount = conf->ThreadCount();
	}
	// we don't want to use all cores in a server by default
	else if (MAX_THREADS > coreCount)
	{
		itsThreadCount = coreCount;
	}

	itsInfo = itsConfiguration->Info();

	itsLeadingDimension = itsConfiguration->LeadingDimension();

	itsPluginIsInitialized = true;
}

void compiled_plugin_base::Run(shared_ptr<info> myTargetInfo, unsigned short threadIndex)
{
	while (AdjustLeadingDimension(myTargetInfo))
	{
		Calculate(myTargetInfo, threadIndex);
	}
}

void compiled_plugin_base::Finish()
{

	if (itsConfiguration->StatisticsEnabled())
	{
		itsTimer->Stop();
		itsConfiguration->Statistics()->AddToProcessingTime(itsTimer->GetTime());
	}

	if (itsConfiguration->FileWriteOption() == kSingleFile)
	{
		WriteToFile(itsInfo);
	}
}

void compiled_plugin_base::Calculate(std::shared_ptr<info> myTargetInfo, unsigned short threadIndex)
{
	itsBaseLogger->Fatal("Top level calculate called");
	exit(1);
}

void compiled_plugin_base::SetParams(std::vector<param>& params)
{
	if (params.empty())
	{
		itsBaseLogger->Fatal("size of target parameter vector is zero");
		exit(1);
	}

	// GRIB 1

	if (itsConfiguration->OutputFileType() == kGRIB1)
	{
		auto n = dynamic_pointer_cast<plugin::neons> (plugin_factory::Instance()->Plugin("neons"));

		for (unsigned int i = 0; i < params.size(); i++)
		{
			long table2Version = itsInfo->Producer().TableVersion();
			long parm_id = n->NeonsDB().GetGridParameterId(table2Version, params[i].Name());

			if (parm_id == -1)
			{
				itsBaseLogger->Warning("Grib1 parameter definitions not found from Neons");
				itsBaseLogger->Warning("table2Version is " + boost::lexical_cast<string> (table2Version) + ", parm_name is " + params[i].Name());
			}

			params[i].GribIndicatorOfParameter(parm_id);
			params[i].GribTableVersion(table2Version);
		}
	}

	itsInfo->Params(params);

	/*
	 * Create data structures.
	 */

	itsInfo->Create();

	/*
	 * Iterators must be reseted since they are at first position after Create()
	 */

	itsInfo->Reset();

	/*
	 * Do not launch more threads than there are things to calculate.
	 */

	if (itsLeadingDimension == kTimeDimension)
	{
		if (itsInfo->SizeTimes() < static_cast<size_t> (itsThreadCount))
		{
			itsThreadCount = static_cast<short> (itsInfo->SizeTimes());
		}
	}
	else if (itsLeadingDimension == kLevelDimension)
	{
		if (itsInfo->SizeLevels() < static_cast<size_t> (itsThreadCount))
		{
			itsThreadCount = static_cast<short> (itsInfo->SizeLevels());
		}
	}

	/*
	 * From the timing perspective at this point plugin initialization is
	 * considered to be done
	 */

	if (itsConfiguration->StatisticsEnabled())
	{
		itsConfiguration->Statistics()->UsedThreadCount(itsThreadCount);
		itsTimer->Stop();
		itsConfiguration->Statistics()->AddToInitTime(itsTimer->GetTime());
		// Start process timing
		itsTimer->Start();
	}
}

#ifdef HAVE_CUDA
void compiled_plugin_base::Unpack(initializer_list<shared_ptr<info>> infos)
{
	auto c = dynamic_pointer_cast<plugin::cache> (plugin_factory::Instance()->Plugin("cache"));

	for (auto it = infos.begin(); it != infos.end(); ++it)
	{
		shared_ptr<info> tempInfo = *it;

		if (!tempInfo->Grid()->PackedData() || tempInfo->Grid()->PackedData()->packedLength == 0)
		{
			// Safeguard: This particular info does not have packed data
			continue;
		}

		assert(tempInfo->Grid()->PackedData()->ClassName() == "simple_packed");

		double* arr;
		size_t N = tempInfo->Grid()->PackedData()->unpackedLength;

		assert(N);

		CUDA_CHECK(cudaMallocHost(reinterpret_cast<void**> (&arr), sizeof(double) * N));

		dynamic_pointer_cast<simple_packed> (tempInfo->Grid()->PackedData())->Unpack(arr, N);

		tempInfo->Data()->Set(arr, N);

		CUDA_CHECK(cudaFreeHost(arr));

		tempInfo->Grid()->PackedData()->Clear();

		if (itsConfiguration->UseCache())
		{
			c->Insert(tempInfo);
		}
	}
}

void compiled_plugin_base::CopyDataFromSimpleInfo(shared_ptr<info> anInfo, info_simple* aSimpleInfo, bool writeToCache)
{
	assert(aSimpleInfo);

	anInfo->Data()->Set(aSimpleInfo->values, aSimpleInfo->size_x * aSimpleInfo->size_y);

	if (anInfo->Grid()->IsPackedData())
	{
		anInfo->Grid()->PackedData()->Clear();
	}

	aSimpleInfo->free_values();

	if (writeToCache && itsConfiguration->UseCache())
	{
		auto c = dynamic_pointer_cast<plugin::cache> (plugin_factory::Instance()->Plugin("cache"));
		c->Insert(anInfo);
	}
}
#endif

bool compiled_plugin_base::CompareGrids(initializer_list<shared_ptr<grid>> grids)
{
	if (grids.size() <= 1)
	{
		throw kUnknownException;
	}

	auto it = grids.begin();
	auto first = *it;

	for (++it; it != grids.end(); ++it)
	{
		if (!*it)
		{
			continue;
		}

		if (*first != **it)
		{
			return false;
		}
	}

	return true;
}

bool compiled_plugin_base::IsMissingValue(initializer_list<double> values)
{
	for (auto it = values.begin(); it != values.end(); ++it)
	{
		if (*it == kFloatMissing)
		{
			return true;
		}
	}

	return false;
}<|endoftext|>


<commit_before>
#include <Hord/LockFile.hpp>

#include <cstdlib>
#include <cstdio>
#include <utility>

#include <unistd.h>
#include <sys/file.h>

#include <Hord/detail/gr_ceformat.hpp>

namespace Hord {

// class LockFile implementation

#define HORD_SCOPE_CLASS LockFile

LockFile::~LockFile() {
	release();
}

LockFile::LockFile(
	String path
) noexcept
	: m_path(std::move(path))
{}

#define HORD_SCOPE_FUNC set_path
namespace {
HORD_DEF_FMT_FQN(
	s_err_immutable,
	"cannot change path to `%s` while lock is active"
);
} // anonymous namespace

void
LockFile::set_path(
	String path
) {
	if (is_active()) {
		HORD_THROW_FMT(
			ErrorCode::lockfile_immutable,
			s_err_immutable,
			m_path
		);
	} else {
		m_path.assign(std::move(path));
	}
}
#undef HORD_SCOPE_FUNC

#define HORD_SCOPE_FUNC acquire
namespace {
HORD_DEF_FMT_FQN(
	s_err_acquire_failed,
	"failed to acquire lock for `%s`"
);
} // anonymous namespace

void
LockFile::acquire() {
	if (!is_active()) {
		handle_type const fd = ::open(
			m_path.c_str(),
			O_CREAT | O_RDONLY,
			S_IRUSR | S_IRGRP | S_IROTH // 444
		);
		if (NULL_HANDLE != fd) {
			if (0 == ::flock(fd, LOCK_EX | LOCK_NB)) {
				m_handle = fd;
			} else {
				::close(fd);
			}
		}
		if (NULL_HANDLE == m_handle) {
			// TODO: add std::strerror()
			HORD_THROW_FMT(
				ErrorCode::lockfile_acquire_failed,
				s_err_acquire_failed,
				m_path
			);
		}
	}
}
#undef HORD_SCOPE_FUNC

#define HORD_SCOPE_FUNC release
void
LockFile::release() noexcept {
	if (is_active()) {
		// TODO: ::remove() on release?
		::close(m_handle);
		m_handle = NULL_HANDLE;
	}
}
#undef HORD_SCOPE_FUNC

#undef HORD_SCOPE_CLASS

} // namespace Hord

<commit_msg>LockFile: corrected immutability error message (was using path instead of m_path).<commit_after>
#include <Hord/LockFile.hpp>

#include <cstdlib>
#include <cstdio>
#include <utility>

#include <unistd.h>
#include <sys/file.h>

#include <Hord/detail/gr_ceformat.hpp>

namespace Hord {

// class LockFile implementation

#define HORD_SCOPE_CLASS LockFile

LockFile::~LockFile() {
	release();
}

LockFile::LockFile(
	String path
) noexcept
	: m_path(std::move(path))
{}

#define HORD_SCOPE_FUNC set_path
namespace {
HORD_DEF_FMT_FQN(
	s_err_immutable,
	"cannot change path to `%s` while lock is active"
);
} // anonymous namespace

void
LockFile::set_path(
	String path
) {
	if (is_active()) {
		HORD_THROW_FMT(
			ErrorCode::lockfile_immutable,
			s_err_immutable,
			path
		);
	} else {
		m_path.assign(std::move(path));
	}
}
#undef HORD_SCOPE_FUNC

#define HORD_SCOPE_FUNC acquire
namespace {
HORD_DEF_FMT_FQN(
	s_err_acquire_failed,
	"failed to acquire lock for `%s`"
);
} // anonymous namespace

void
LockFile::acquire() {
	if (!is_active()) {
		handle_type const fd = ::open(
			m_path.c_str(),
			O_CREAT | O_RDONLY,
			S_IRUSR | S_IRGRP | S_IROTH // 444
		);
		if (NULL_HANDLE != fd) {
			if (0 == ::flock(fd, LOCK_EX | LOCK_NB)) {
				m_handle = fd;
			} else {
				::close(fd);
			}
		}
		if (NULL_HANDLE == m_handle) {
			// TODO: add std::strerror()
			HORD_THROW_FMT(
				ErrorCode::lockfile_acquire_failed,
				s_err_acquire_failed,
				m_path
			);
		}
	}
}
#undef HORD_SCOPE_FUNC

#define HORD_SCOPE_FUNC release
void
LockFile::release() noexcept {
	if (is_active()) {
		// TODO: ::remove() on release?
		::close(m_handle);
		m_handle = NULL_HANDLE;
	}
}
#undef HORD_SCOPE_FUNC

#undef HORD_SCOPE_CLASS

} // namespace Hord

<|endoftext|>