<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/lib/p9_hcd_common.H $                 */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2015,2016                                                    */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_hcd_common.H
/// @brief common hcode includes
///

// *HWP HWP Owner          : David Du       <daviddu@us.ibm.com>
// *HWP Backup HWP Owner   : Greg Still     <stillgs@us.ibm.com>
// *HWP FW Owner           : Sangeetha T S  <sangeet2@in.ibm.com>
// *HWP Team               : PM
// *HWP Consumed by        : SBE:SGPE:CME
// *HWP Level              : 2

#ifndef __P9_HCD_COMMON_H__
#define __P9_HCD_COMMON_H__

//-------------------------
// Macros
//-------------------------

// Create a multi-bit mask of \a n bits starting at bit \a b
#define BITS64(b, n) ((0xffffffffffffffffull << (64 - (n))) >> (b))

// Create a single bit mask at bit \a b
#define BIT64(b) BITS64((b), 1)

// The BUF_* macros apply operations to a newly constructed buffer
#define BUF_SET(bit)   fapi2::buffer<uint64_t>().setBit<bit>()
#define BUF_UNSET(bit) fapi2::buffer<uint64_t>().flush<1>().clearBit<bit>()
#define BUF_INSERT(start,size,val) \
    fapi2::buffer<uint64_t>().insertFromRight<start,size>(val)
#define BUF_REPLACE(start,size,val) \
    fapi2::buffer<uint64_t>().flush<1>().insertFromRight<start,size>(val)

// The following DATA_* and MASK_* macros assume you have
// "fapi2::buffer<uint64_t> l_data64" declared

// The DATA_* macros apply operations to a buffer contains existing data
#define DATA_BIT(buf,op,bit)             buf.op##Bit<bit>()
#define DATA_SET(bit)                    DATA_BIT(l_data64,set,bit)
#define DATA_UNSET(bit)                  DATA_BIT(l_data64,clear,bit)
#define DATA_FIELD(buf,start,size,val)   buf.insertFromRight<start,size>(val)
#define DATA_INSERT(start,size,val)      DATA_FIELD(l_data64,start,size,val)

// The MASK_* macros apply operations to a buffer to create a new data mask
// data previously stored in the buffer will be overwritten.
#define MASK_FLUSH(buf,mask)             buf.flush<mask>()
#define MASK_ZERO                        MASK_FLUSH(l_data64,0)
#define MASK_ALL                         MASK_FLUSH(l_data64,1)
#define MASK_BIT(buf,mask,op,bit)        buf.flush<mask>().op##Bit<bit>()
#define MASK_SET(bit)                    MASK_BIT(l_data64,0,set,bit)
#define MASK_UNSET(bit)                  MASK_BIT(l_data64,1,clear,bit)
#define MASK_FIELD(buf,mask,start,size,val) \
    buf.flush<mask>().insertFromRight<start,size>(val)
#define MASK_OR(start,size,val)          MASK_FIELD(l_data64,0,start,size,val)
#define MASK_AND(start,size,val)         MASK_FIELD(l_data64,1,start,size,val)
#define MASK_CLR(start,size,val)         MASK_FIELD(l_data64,0,start,size,val)

//-------------------------
// Constants
//-------------------------

namespace p9hcd
{

// Constants to calculate hcd poll timeout intervals
enum P9_HCD_COMMON_TIMEOUT_CONSTANTS
{
    CYCLES_PER_MS       = 500000, // PPE FREQ 500MHZ
    INSTS_PER_POLL_LOOP = 8       //
};

// Init Vectors for Register Setup
enum P9_HCD_COMMON_INIT_VECTORS
{
    // 0     -  CHIPLET_ENABLE
    // 1     -  PCB_EP_RESET
    // 3     -  PLL_TEST_EN
    // 4     -  PLLRST
    // 5     -  PLLBYP
    // 12    -  VITL_MPW1
    // 13    -  VITL_MPW2
    // 14    -  VITL_MPW3
    // 18    -  FENCE_EN
    NET_CTRL0_INIT_VECTOR = (BIT64(0) | BIT64(1) | BITS64(3, 3) | BITS64(12, 3) | BIT64(18)),
    HANG_PULSE1_INIT_VECTOR = BIT64(5)
};

// Clock Control Constants
enum P9_HCD_COMMON_CLK_CTRL_CONSTANTS
{
    CLK_STOP_CMD                             = BIT64(0),
    CLK_START_CMD                            = BIT64(1),
    CLK_SLAVE_MODE                           = BIT64(2),
    CLK_MASTER_MODE                          = BIT64(3),
    CLK_REGION_DPLL                          = BIT64(14),
    CLK_REGION_L2                            = BITS64(8, 2),
    CLK_REGION_ALL_BUT_DPLL_L2               = BITS64(4, 4) | BITS64(10, 4),
    CLK_REGION_ALL                           = BITS64(4, 11),
    CLK_THOLD_ALL                            = BITS64(48, 3),
    CLK_THOLD_NSL_ARY                        = BITS64(49, 2)
};

// Clock Control Vectors
enum P9_HCD_COMMON_CLK_CTRL_VECTORS
{
    CLK_START_REGION_ALL_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_ALL | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ALL_THOLD_ALL =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_ALL | CLK_THOLD_ALL),
    CLK_START_REGION_ALL_BUT_DPLL_L2_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_ALL_BUT_DPLL_L2 | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ALL_BUT_DPLL_L2_THOLD_ALL =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_ALL_BUT_DPLL_L2 | CLK_THOLD_ALL),
    CLK_START_REGION_L2_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_L2 | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_L2_THOLD_ALL =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_L2 | CLK_THOLD_ALL),
    CLK_START_REGION_DPLL_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_DPLL | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_DPLL_THOLD_ALL =
        (CLK_START_CMD | CLK_MASTER_MODE | CLK_REGION_DPLL | CLK_THOLD_ALL)
};

// SCAN0 Constants
enum P9_HCD_COMMON_SCAN0_CONSTANTS
{
    SCAN0_REGION_ALL                         = 0x7FF,
    SCAN0_REGION_ALL_BUT_PLL                 = 0x7FE,
    SCAN0_REGION_PLL                         = 0x001,
    SCAN0_REGION_CORE_ONLY                   = 0x300,
    SCAN0_TYPE_ALL_BUT_GPTR_REPR_TIME        = 0xDCF,
    SCAN0_TYPE_GPTR_REPR_TIME                = 0x230,
    SCAN0_TYPE_REPR_TIME                     = 0x030,
    SCAN0_TYPE_GPTR                          = 0x200,
    SCAN0_TYPE_FUNC_BNDY                     = 0x808
};
//OCC FLag defines
enum PM_GPE_OCCFLG_DEFS
{
    SGPE_ACTIVE    = 8
};

// XSR defines
enum XSR_DEFS
{
    HALTED_STATE    = 0
};

// XCR defines
enum XCR_DEFS
{
    CLEAR_DEBUG_STATUS = 0,
    HALT               = 1,
    RESUME             = 2,
    SINGLE_STEP        = 3,
    TOGGLE_XSR_TRH     = 4,
    SOFT_RESET         = 5,
    HARD_RESET         = 6,
    FORCE_HALT         = 7
};

} // END OF NAMESPACE p9hcd

/// @todo needs to review this
/// SCAN Repeats(from P8)
#define GENERIC_CC_SCAN0_MAXIMUM   8191
#define SCAN0_FUNC_FLUSH_LENGTH    8000
#define SCAN0_GPTR_FLUSH_LENGTH    14000
#define P9_HCD_SCAN_FUNC_REPEAT    \
    ((SCAN0_FUNC_FLUSH_LENGTH / GENERIC_CC_SCAN0_MAXIMUM)+1)
#define P9_HCD_SCAN_GPTR_REPEAT    \
    ((SCAN0_GPTR_FLUSH_LENGTH / GENERIC_CC_SCAN0_MAXIMUM)+1)

/// @todo remove these once correct header contains them
/// Scom addresses missing from p9_quad_scom_addresses.H
#define EQ_QPPM_QCCR_WCLEAR              0x100F01BE
#define EQ_QPPM_QCCR_WOR                 0x100F01BF

#endif  // __P9_HCD_COMMON_H__
<commit_msg>HWP-CORE/CACHE: Update Istep 4 procedures regressed on model 34<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/lib/p9_hcd_common.H $                 */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2015,2016                                                    */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_hcd_common.H
/// @brief common hcode includes
///

// *HWP HWP Owner          : David Du       <daviddu@us.ibm.com>
// *HWP Backup HWP Owner   : Greg Still     <stillgs@us.ibm.com>
// *HWP FW Owner           : Sangeetha T S  <sangeet2@in.ibm.com>
// *HWP Team               : PM
// *HWP Consumed by        : SBE:SGPE:CME
// *HWP Level              : 2

#ifndef __P9_HCD_COMMON_H__
#define __P9_HCD_COMMON_H__

//-------------------------
// Macros
//-------------------------

// Create a multi-bit mask of \a n bits starting at bit \a b
#define BITS64(b, n) ((0xffffffffffffffffull << (64 - (n))) >> (b))
#define BITS32(b, n) ((0xffffffff            << (32 - (n))) >> (b))
#define BITS16(b, n) ((0xffff                << (16 - (n))) >> (b))
#define BITS8(b, n)  ((0xff                  << (8  - (n))) >> (b))

// Create a single bit mask at bit \a b
#define BIT64(b) BITS64((b), 1)
#define BIT32(b) BITS32((b), 1)
#define BIT16(b) BITS16((b), 1)
#define BIT8(b)  BITS8((b), 1)

// Create a amount of shift to bit location \a b
#define SHIFT64(b) (63-b)
#define SHIFT32(b) (31-b)
#define SHIFT16(b) (15-b)
#define SHIFT8(b)  (7-b)

// The BUF_* macros apply operations to a newly constructed buffer
#define BUF_SET(bit)   fapi2::buffer<uint64_t>().setBit<bit>()
#define BUF_UNSET(bit) fapi2::buffer<uint64_t>().flush<1>().clearBit<bit>()
#define BUF_INSERT(start,size,val) \
    fapi2::buffer<uint64_t>().insertFromRight<start,size>(val)
#define BUF_REPLACE(start,size,val) \
    fapi2::buffer<uint64_t>().flush<1>().insertFromRight<start,size>(val)
// The following DATA_* and MASK_* macros assume you have
// "fapi2::buffer<uint64_t> l_data64" declared

// The DATA_* macros apply operations to a buffer contains existing data
#define DATA_BIT(buf,op,bit)             buf.op##Bit<bit>()
#define DATA_SET(bit)                    DATA_BIT(l_data64,set,bit)
#define DATA_UNSET(bit)                  DATA_BIT(l_data64,clear,bit)
#define DATA_FIELD(buf,start,size,val)   buf.insertFromRight<start,size>(val)
#define DATA_INSERT(start,size,val)      DATA_FIELD(l_data64,start,size,val)

// The MASK_* macros apply operations to a buffer to create a new data mask
// data previously stored in the buffer will be overwritten.
#define MASK_FLUSH(buf,mask)             buf.flush<mask>()
#define MASK_ZERO                        MASK_FLUSH(l_data64,0)
#define MASK_ALL                         MASK_FLUSH(l_data64,1)
#define MASK_BIT(buf,mask,op,bit)        buf.flush<mask>().op##Bit<bit>()
#define MASK_SET(bit)                    MASK_BIT(l_data64,0,set,bit)
#define MASK_UNSET(bit)                  MASK_BIT(l_data64,1,clear,bit)
#define MASK_FIELD(buf,mask,start,size,val) \
    buf.flush<mask>().insertFromRight<start,size>(val)
#define MASK_OR(start,size,val)          MASK_FIELD(l_data64,0,start,size,val)
#define MASK_AND(start,size,val)         MASK_FIELD(l_data64,1,start,size,val)
#define MASK_CLR(start,size,val)         MASK_FIELD(l_data64,0,start,size,val)

//-------------------------
// Constants
//-------------------------

namespace p9hcd
{

// Bit masks used by CME hcode
enum P9_HCD_CME_CORE_MASKS
{
    LEFT_CORE  = 0x2,
    RIGHT_CORE = 0x1,
    BOTH_CORES = 0x3,
    NO_CORE    = 0x0
};

// Control parameters for PCB Aribter
enum P9_HCD_PCB_ARBITER_CTRL
{
    REQUEST_ARBITER = 1,
    RELEASE_ARBITER = 0
};

// Constants to calculate hcd poll timeout intervals
enum P9_HCD_COMMON_TIMEOUT_CONSTANTS
{
    CYCLES_PER_MS       = 500000, // PPE FREQ 500MHZ
    INSTS_PER_POLL_LOOP = 8       //
};

// Init Vectors for Register Setup
enum P9_HCD_COMMON_INIT_VECTORS
{
    // 0     -  CHIPLET_ENABLE
    // 1     -  PCB_EP_RESET
    // 3     -  PLL_TEST_EN
    // 4     -  PLLRST
    // 5     -  PLLBYP
    // 12    -  VITL_MPW1
    // 13    -  VITL_MPW2
    // 14    -  VITL_MPW3
    // 18    -  FENCE_EN
    NET_CTRL0_INIT_VECTOR = (BIT64(0) | BIT64(1) | BITS64(3, 3) | BITS64(12, 3) | BIT64(18)),
    HANG_PULSE1_INIT_VECTOR = BIT64(5)
};

// Clock Control Constants
enum P9_HCD_COMMON_CLK_CTRL_CONSTANTS
{
    CLK_STOP_CMD                             = BIT64(0),
    CLK_START_CMD                            = BIT64(1),
    CLK_SLAVE_MODE                           = BIT64(2),
    CLK_MASTER_MODE                          = BIT64(3),
    CLK_REGION_ANEP                          = BIT64(10),
    CLK_REGION_DPLL                          = BIT64(14),
    CLK_REGION_L2                            = BITS64(8, 2),
    CLK_REGION_ALL_BUT_DPLL_L2               = BITS64(4, 4) | BITS64(10, 4),
    CLK_REGION_ALL                           = BITS64(4, 11),
    CLK_THOLD_ALL                            = BITS64(48, 3),
    CLK_THOLD_NSL_ARY                        = BITS64(49, 2)
};

// Clock Control Vectors
enum P9_HCD_COMMON_CLK_CTRL_VECTORS
{
    CLK_START_REGION_ALL_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_ALL | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ALL_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_ALL | CLK_THOLD_ALL),
    CLK_START_REGION_ALL_BUT_DPLL_L2_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_ALL_BUT_DPLL_L2 | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ALL_BUT_DPLL_L2_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_ALL_BUT_DPLL_L2 | CLK_THOLD_ALL),
    CLK_START_REGION_L2_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_L2 | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_L2_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_L2 | CLK_THOLD_ALL),
    CLK_START_REGION_DPLL_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_DPLL | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_DPLL_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_DPLL | CLK_THOLD_ALL),
    CLK_START_REGION_ANEP_THOLD_NSL_ARY =
        (CLK_START_CMD | CLK_REGION_ANEP | CLK_THOLD_NSL_ARY),
    CLK_START_REGION_ANEP_THOLD_ALL =
        (CLK_START_CMD | CLK_REGION_ANEP | CLK_THOLD_ALL)
};

// SCAN0 Constants
enum P9_HCD_COMMON_SCAN0_CONSTANTS
{
    SCAN0_REGION_ALL                         = 0x7FF,
    SCAN0_REGION_ALL_BUT_PLL                 = 0x7FE,
    SCAN0_REGION_ALL_BUT_ANEP_PLL            = 0x7EE,
    SCAN0_REGION_PLL                         = 0x001,
    SCAN0_REGION_DPLL_ANEP                   = 0x011,
    SCAN0_REGION_CORE_ONLY                   = 0x300,
    SCAN0_REGION_PERV_CORE                   = 0x700,
    SCAN0_TYPE_ALL_BUT_GPTR_REPR_TIME        = 0xDCF,
    SCAN0_TYPE_GPTR_REPR_TIME                = 0x230,
    SCAN0_TYPE_REPR_TIME                     = 0x030,
    SCAN0_TYPE_GPTR                          = 0x200,
    SCAN0_TYPE_FUNC                          = 0x800,
    SCAN0_TYPE_FUNC_BNDY                     = 0x808
};
//OCC FLag defines
enum PM_GPE_OCCFLG_DEFS
{
    SGPE_ACTIVE    = 8
};

// XSR defines
enum XSR_DEFS
{
    HALTED_STATE    = 0
};

// XCR defines
enum XCR_DEFS
{
    CLEAR_DEBUG_STATUS = 0,
    HALT               = 1,
    RESUME             = 2,
    SINGLE_STEP        = 3,
    TOGGLE_XSR_TRH     = 4,
    SOFT_RESET         = 5,
    HARD_RESET         = 6,
    FORCE_HALT         = 7
};

} // END OF NAMESPACE p9hcd

/// @todo needs to review this
/// SCAN Repeats(from P8)
/*
#define GENERIC_CC_SCAN0_MAXIMUM   8191
#define SCAN0_FUNC_FLUSH_LENGTH    8000
#define SCAN0_GPTR_FLUSH_LENGTH    14000
#define P9_HCD_SCAN_FUNC_REPEAT    \
    ((SCAN0_FUNC_FLUSH_LENGTH / GENERIC_CC_SCAN0_MAXIMUM)+1)
#define P9_HCD_SCAN_GPTR_REPEAT    \
    ((SCAN0_GPTR_FLUSH_LENGTH / GENERIC_CC_SCAN0_MAXIMUM)+1)
*/
#define P9_HCD_SCAN_FUNC_REPEAT 40
#define P9_HCD_SCAN_GPTR_REPEAT 40

/// @todo remove these once correct header contains them
/// Scom addresses missing from p9_quad_scom_addresses.H
#define EQ_QPPM_QCCR_WOR                 0x100F01BF
#define CME_LCL_SICR_OR                  0xc0000510
#define CME_LCL_SICR_CLR                 0xc0000518
#define CME_LCL_SISR                     0xc0000520

#endif  // __P9_HCD_COMMON_H__
<|endoftext|>


<commit_before>/*
 * 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.
 *
 *
 */
#include <gtest/gtest.h>
#include <vector>
#include <stdio.h>
#include <pcl/common/time.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/search/pcl_search.h>

using namespace std;
using namespace pcl;
using namespace octree;

// helper class for priority queue
class prioPointQueueEntry
{
public:
  prioPointQueueEntry ()
  {
  }
  prioPointQueueEntry (PointXYZ& point_arg, double pointDistance_arg, int pointIdx_arg)
  {
    point_ = point_arg;
    pointDistance_ = pointDistance_arg;
    pointIdx_ = pointIdx_arg;
  }

  bool
  operator< (const prioPointQueueEntry& rhs_arg) const
  {
    return (this->pointDistance_ < rhs_arg.pointDistance_);
  }

  PointXYZ point_;
  double pointDistance_;int pointIdx_;
};

TEST (PCL, Octree_Pointcloud_Nearest_K_Neighbour_Search)
{
  const unsigned int test_runs = 1;
  unsigned int test_id;

  // instantiate point cloud
  PointCloud<PointXYZ>::Ptr cloudIn (new PointCloud<PointXYZ> ());

  size_t i;
  srand (time (NULL));
  unsigned int K;

  std::priority_queue<prioPointQueueEntry, std::vector<prioPointQueueEntry, Eigen::aligned_allocator<
      prioPointQueueEntry> > > pointCandidates;

  // create octree
  pcl::search::Search<PointXYZ>* octree = new pcl::search::Octree<PointXYZ> (0.1);

  std::vector<int> k_indices;
  std::vector<float> k_sqr_distances;

  std::vector<int> k_indices_bruteforce;
  std::vector<float> k_sqr_distances_bruteforce;

  for (test_id = 0; test_id < test_runs; test_id++)
  {
    // define a random search point
    PointXYZ searchPoint (10.0 * ((double)rand () / (double)RAND_MAX), 10.0 * ((double)rand () / (double)RAND_MAX),
                          10.0 * ((double)rand () / (double)RAND_MAX));

    K = rand () % 10;

    // generate point cloud
    cloudIn->width = 1000;
    cloudIn->height = 1;
    cloudIn->points.resize (cloudIn->width * cloudIn->height);
    for (i = 0; i < 1000; i++)
    {
      cloudIn->points[i] = PointXYZ (5.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX));
    }

    double pointDist;

    k_indices.clear ();
    k_sqr_distances.clear ();

    k_indices_bruteforce.clear ();
    k_sqr_distances_bruteforce.clear ();

    // push all points and their distance to the search point into a priority queue - bruteforce approach.
    for (i = 0; i < cloudIn->points.size (); i++)
    {
      pointDist = ((cloudIn->points[i].x - searchPoint.x) * (cloudIn->points[i].x - searchPoint.x)
          + (cloudIn->points[i].y - searchPoint.y) * (cloudIn->points[i].y - searchPoint.y) + (cloudIn->points[i].z
          - searchPoint.z) * (cloudIn->points[i].z - searchPoint.z));

      prioPointQueueEntry pointEntry (cloudIn->points[i], pointDist, i);

      pointCandidates.push (pointEntry);
    }

    // pop priority queue until we have the nearest K elements
    while (pointCandidates.size () > K)
      pointCandidates.pop ();

    // copy results into vectors
    while (pointCandidates.size ())
    {
      k_indices_bruteforce.push_back (pointCandidates.top ().pointIdx_);
      k_sqr_distances_bruteforce.push_back (pointCandidates.top ().pointDistance_);

      pointCandidates.pop ();
    }

    // octree nearest neighbor search
    octree->setInputCloud (cloudIn);
    octree->nearestKSearch (searchPoint, (int)K, k_indices, k_sqr_distances);

    ASSERT_EQ ( k_indices.size() , k_indices_bruteforce.size() );

    // compare nearest neighbor results of octree with bruteforce search
    i = 0;
    while (k_indices_bruteforce.size ())
    {
      ASSERT_EQ ( k_indices.back() , k_indices_bruteforce.back() );
      EXPECT_NEAR (k_sqr_distances.back(), k_sqr_distances_bruteforce.back(), 1e-4);

      k_indices_bruteforce.pop_back();
      k_indices.pop_back();

      k_sqr_distances_bruteforce.pop_back();
      k_sqr_distances.pop_back();
    }
  }
}

TEST (PCL, Octree_Pointcloud_Approx_Nearest_Neighbour_Search)
{
  const unsigned int test_runs = 100;
  unsigned int test_id;
  unsigned int bestMatchCount = 0;

  // instantiate point cloud
  PointCloud<PointXYZ>::Ptr cloudIn (new PointCloud<PointXYZ> ());

  size_t i;
  srand (time (NULL));

  double voxelResolution = 0.1;

  // create octree
  pcl::search::Search<PointXYZ>* octree = new pcl::search::Octree<PointXYZ> (voxelResolution);

  for (test_id = 0; test_id < test_runs; test_id++)
  {
    // define a random search point
    PointXYZ searchPoint (10.0 * ((double)rand () / (double)RAND_MAX), 10.0 * ((double)rand () / (double)RAND_MAX),
                          10.0 * ((double)rand () / (double)RAND_MAX));

    // generate point cloud
    cloudIn->width = 1000;
    cloudIn->height = 1;
    cloudIn->points.resize (cloudIn->width * cloudIn->height);
    for (i = 0; i < 1000; i++)
      cloudIn->points[i] = PointXYZ (5.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX));
    // brute force search
    double pointDist;
    double BFdistance = numeric_limits<double>::max ();
    int BFindex = 0;

    for (i = 0; i < cloudIn->points.size (); i++)
    {
      pointDist = ((cloudIn->points[i].x - searchPoint.x) * (cloudIn->points[i].x - searchPoint.x)
          + (cloudIn->points[i].y - searchPoint.y) * (cloudIn->points[i].y - searchPoint.y) + (cloudIn->points[i].z
          - searchPoint.z) * (cloudIn->points[i].z - searchPoint.z));

      if (pointDist < BFdistance)
      {
        BFindex = i;
        BFdistance = pointDist;
      }
    }

    int ANNindex;
    float ANNdistance;

    octree->setInputCloud (cloudIn);
/*    octree->approxNearestSearch (searchPoint, ANNindex, ANNdistance);

    if (BFindex == ANNindex)
    {
      EXPECT_NEAR (ANNdistance, BFdistance, 1e-4);
      bestMatchCount++;
    }*/
  }
  // we should have found the absolute nearest neighbor at least once
  //ASSERT_EQ ( (bestMatchCount > 0) , true);
}
#if 0
TEST (PCL, Octree_RadiusSearch_GPU)
{
  PointCloud<PointXYZ>::Ptr cloudIn (new PointCloud<PointXYZ> ());
  // generate point cloud data
  cloudIn->width = 1000;
  cloudIn->height = 1;
  cloudIn->points.resize (cloudIn->width * cloudIn->height);

  int i=0;
  for (i = 0; i < 1000; i++)
  {
    cloudIn->points[i] = PointXYZ (10.0 * ((double)rand () / (double)RAND_MAX),
        10.0 * ((double)rand () / (double)RAND_MAX),
        5.0 * ((double)rand () / (double)RAND_MAX));
  }

  Search<PointXYZ>* octree = new pcl::octree::OctreeWrapper<PointXYZ>(0.1f);
  octree->setInputCloud(cloudIn);

  std::vector <PointXYZ > point;
  const PointXYZ searchPoint (10.0 * ((double)rand () / (double)RAND_MAX), 10.0 * ((double)rand () / (double)RAND_MAX),
      10.0 * ((double)rand () / (double)RAND_MAX));
  point.push_back(searchPoint);
  point.push_back(searchPoint);
  point.push_back(searchPoint);
  double searchRadius = 5.0 * ((double)rand () / (double)RAND_MAX);
  double radius =5;
  vector < double > radiuses;
  radiuses.push_back(radius);
  radiuses.push_back(radius);
  radiuses.push_back(radius);
  std::vector<std::vector<int> > k_indices;
  std::vector<std::vector<float> > k_distances;
  int max_nn = -1;

  octree->radiusSearch (point, radiuses, k_indices,k_distances,max_nn );
}

#endif
TEST (PCL, Octree_Pointcloud_Neighbours_Within_Radius_Search)
{
  const unsigned int test_runs = 100;
  unsigned int test_id;

  // instantiate point clouds
  PointCloud<PointXYZ>::Ptr cloudIn (new PointCloud<PointXYZ> ());
  PointCloud<PointXYZ>::Ptr cloudOut (new PointCloud<PointXYZ> ());

  size_t i;

  srand (time (NULL));

  for (test_id = 0; test_id < test_runs; test_id++)
  {
    // define a random search point
    PointXYZ searchPoint (10.0 * ((double)rand () / (double)RAND_MAX), 10.0 * ((double)rand () / (double)RAND_MAX),
                          10.0 * ((double)rand () / (double)RAND_MAX));

    cloudIn->width = 1000;
    cloudIn->height = 1;
    cloudIn->points.resize (cloudIn->width * cloudIn->height);

    // generate point cloud data
    for (i = 0; i < 1000; i++)
    {
      cloudIn->points[i] = PointXYZ (10.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX),
                                     5.0 * ((double)rand () / (double)RAND_MAX));
    }

    pcl::search::Search<PointXYZ>* octree = new pcl::search::Octree<PointXYZ> (0.001);

    // build octree
    double pointDist;
    double searchRadius = 5.0 * ((double)rand () / (double)RAND_MAX);

    // bruteforce radius search
    vector<int> cloudSearchBruteforce;
    for (i = 0; i < cloudIn->points.size (); i++)
    {
      pointDist = sqrt (
                        (cloudIn->points[i].x - searchPoint.x) * (cloudIn->points[i].x - searchPoint.x)
                            + (cloudIn->points[i].y - searchPoint.y) * (cloudIn->points[i].y - searchPoint.y)
                            + (cloudIn->points[i].z - searchPoint.z) * (cloudIn->points[i].z - searchPoint.z));

      if (pointDist <= searchRadius)
      {
        // add point candidates to vector list
        cloudSearchBruteforce.push_back ((int)i);
      }
    }

    vector<int> cloudNWRSearch;
    vector<float> cloudNWRRadius;

    // execute octree radius search
    octree->setInputCloud (cloudIn);
    octree->radiusSearch (searchPoint, searchRadius, cloudNWRSearch, cloudNWRRadius);

    ASSERT_EQ ( cloudNWRRadius.size() , cloudSearchBruteforce.size());

    // check if result from octree radius search can be also found in bruteforce search
    std::vector<int>::const_iterator current = cloudNWRSearch.begin();
    while (current != cloudNWRSearch.end())
    {
      pointDist = sqrt (
          (cloudIn->points[*current].x-searchPoint.x) * (cloudIn->points[*current].x-searchPoint.x) +
          (cloudIn->points[*current].y-searchPoint.y) * (cloudIn->points[*current].y-searchPoint.y) +
          (cloudIn->points[*current].z-searchPoint.z) * (cloudIn->points[*current].z-searchPoint.z)
      );

      ASSERT_EQ ( (pointDist<=searchRadius) , true);

      ++current;
    }

    // check if result limitation works
    octree->radiusSearch(searchPoint, searchRadius, cloudNWRSearch, cloudNWRRadius, 5);
    ASSERT_EQ ( cloudNWRRadius.size() <= 5, true);
  }
}

/* ---[ */
int
main (int argc, char** argv)
{
  testing::InitGoogleTest (&argc, argv);
  return (RUN_ALL_TESTS ());
}
/* ]--- */
<commit_msg>fixed compiler warnings<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.
 *
 *
 */
#include <gtest/gtest.h>
#include <vector>
#include <stdio.h>
#include <pcl/common/time.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/search/pcl_search.h>

using namespace std;
using namespace pcl;
using namespace octree;

// helper class for priority queue
class prioPointQueueEntry
{
public:
  prioPointQueueEntry ()
  {
  }
  prioPointQueueEntry (PointXYZ& point_arg, double pointDistance_arg, int pointIdx_arg)
  {
    point_ = point_arg;
    pointDistance_ = pointDistance_arg;
    pointIdx_ = pointIdx_arg;
  }

  bool
  operator< (const prioPointQueueEntry& rhs_arg) const
  {
    return (this->pointDistance_ < rhs_arg.pointDistance_);
  }

  PointXYZ point_;
  double pointDistance_;int pointIdx_;
};

TEST (PCL, Octree_Pointcloud_Nearest_K_Neighbour_Search)
{
  const unsigned int test_runs = 1;
  unsigned int test_id;

  // instantiate point cloud
  PointCloud<PointXYZ>::Ptr cloudIn (new PointCloud<PointXYZ> ());

  size_t i;
  srand (time (NULL));
  unsigned int K;

  std::priority_queue<prioPointQueueEntry, std::vector<prioPointQueueEntry, Eigen::aligned_allocator<
      prioPointQueueEntry> > > pointCandidates;

  // create octree
  pcl::search::Search<PointXYZ>* octree = new pcl::search::Octree<PointXYZ> (0.1);

  std::vector<int> k_indices;
  std::vector<float> k_sqr_distances;

  std::vector<int> k_indices_bruteforce;
  std::vector<float> k_sqr_distances_bruteforce;

  for (test_id = 0; test_id < test_runs; test_id++)
  {
    // define a random search point
    PointXYZ searchPoint (10.0 * ((double)rand () / (double)RAND_MAX), 10.0 * ((double)rand () / (double)RAND_MAX),
                          10.0 * ((double)rand () / (double)RAND_MAX));

    K = rand () % 10;

    // generate point cloud
    cloudIn->width = 1000;
    cloudIn->height = 1;
    cloudIn->points.resize (cloudIn->width * cloudIn->height);
    for (i = 0; i < 1000; i++)
    {
      cloudIn->points[i] = PointXYZ (5.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX));
    }

    double pointDist;

    k_indices.clear ();
    k_sqr_distances.clear ();

    k_indices_bruteforce.clear ();
    k_sqr_distances_bruteforce.clear ();

    // push all points and their distance to the search point into a priority queue - bruteforce approach.
    for (i = 0; i < cloudIn->points.size (); i++)
    {
      pointDist = ((cloudIn->points[i].x - searchPoint.x) * (cloudIn->points[i].x - searchPoint.x)
          + (cloudIn->points[i].y - searchPoint.y) * (cloudIn->points[i].y - searchPoint.y) + (cloudIn->points[i].z
          - searchPoint.z) * (cloudIn->points[i].z - searchPoint.z));

      prioPointQueueEntry pointEntry (cloudIn->points[i], pointDist, i);

      pointCandidates.push (pointEntry);
    }

    // pop priority queue until we have the nearest K elements
    while (pointCandidates.size () > K)
      pointCandidates.pop ();

    // copy results into vectors
    while (pointCandidates.size ())
    {
      k_indices_bruteforce.push_back (pointCandidates.top ().pointIdx_);
      k_sqr_distances_bruteforce.push_back (pointCandidates.top ().pointDistance_);

      pointCandidates.pop ();
    }

    // octree nearest neighbor search
    octree->setInputCloud (cloudIn);
    octree->nearestKSearch (searchPoint, (int)K, k_indices, k_sqr_distances);

    ASSERT_EQ ( k_indices.size() , k_indices_bruteforce.size() );

    // compare nearest neighbor results of octree with bruteforce search
    i = 0;
    while (k_indices_bruteforce.size ())
    {
      ASSERT_EQ ( k_indices.back() , k_indices_bruteforce.back() );
      EXPECT_NEAR (k_sqr_distances.back(), k_sqr_distances_bruteforce.back(), 1e-4);

      k_indices_bruteforce.pop_back();
      k_indices.pop_back();

      k_sqr_distances_bruteforce.pop_back();
      k_sqr_distances.pop_back();
    }
  }
}

#if 0
TEST (PCL, Octree_Pointcloud_Approx_Nearest_Neighbour_Search)
{
  const unsigned int test_runs = 100;
  unsigned int test_id;
  unsigned int bestMatchCount = 0;

  // instantiate point cloud
  PointCloud<PointXYZ>::Ptr cloudIn (new PointCloud<PointXYZ> ());

  size_t i;
  srand (time (NULL));

  double voxelResolution = 0.1;

  // create octree
  pcl::search::Search<PointXYZ>* octree = new pcl::search::Octree<PointXYZ> (voxelResolution);

  for (test_id = 0; test_id < test_runs; test_id++)
  {
    // define a random search point
    PointXYZ searchPoint (10.0 * ((double)rand () / (double)RAND_MAX), 10.0 * ((double)rand () / (double)RAND_MAX),
                          10.0 * ((double)rand () / (double)RAND_MAX));

    // generate point cloud
    cloudIn->width = 1000;
    cloudIn->height = 1;
    cloudIn->points.resize (cloudIn->width * cloudIn->height);
    for (i = 0; i < 1000; i++)
      cloudIn->points[i] = PointXYZ (5.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX));
    // brute force search
    double pointDist;
    double BFdistance = numeric_limits<double>::max ();
    int BFindex = 0;

    for (i = 0; i < cloudIn->points.size (); i++)
    {
      pointDist = ((cloudIn->points[i].x - searchPoint.x) * (cloudIn->points[i].x - searchPoint.x)
          + (cloudIn->points[i].y - searchPoint.y) * (cloudIn->points[i].y - searchPoint.y) + (cloudIn->points[i].z
          - searchPoint.z) * (cloudIn->points[i].z - searchPoint.z));

      if (pointDist < BFdistance)
      {
        BFindex = i;
        BFdistance = pointDist;
      }
    }

    int ANNindex;
    float ANNdistance;

    octree->setInputCloud (cloudIn);
    octree->approxNearestSearch (searchPoint, ANNindex, ANNdistance);

    if (BFindex == ANNindex)
    {
      EXPECT_NEAR (ANNdistance, BFdistance, 1e-4);
      bestMatchCount++;
    }
  }
  // we should have found the absolute nearest neighbor at least once
  //ASSERT_EQ ( (bestMatchCount > 0) , true);
}
#endif
#if 0
TEST (PCL, Octree_RadiusSearch_GPU)
{
  PointCloud<PointXYZ>::Ptr cloudIn (new PointCloud<PointXYZ> ());
  // generate point cloud data
  cloudIn->width = 1000;
  cloudIn->height = 1;
  cloudIn->points.resize (cloudIn->width * cloudIn->height);

  int i=0;
  for (i = 0; i < 1000; i++)
  {
    cloudIn->points[i] = PointXYZ (10.0 * ((double)rand () / (double)RAND_MAX),
        10.0 * ((double)rand () / (double)RAND_MAX),
        5.0 * ((double)rand () / (double)RAND_MAX));
  }

  Search<PointXYZ>* octree = new pcl::octree::OctreeWrapper<PointXYZ>(0.1f);
  octree->setInputCloud(cloudIn);

  std::vector <PointXYZ > point;
  const PointXYZ searchPoint (10.0 * ((double)rand () / (double)RAND_MAX), 10.0 * ((double)rand () / (double)RAND_MAX),
      10.0 * ((double)rand () / (double)RAND_MAX));
  point.push_back(searchPoint);
  point.push_back(searchPoint);
  point.push_back(searchPoint);
  double searchRadius = 5.0 * ((double)rand () / (double)RAND_MAX);
  double radius =5;
  vector < double > radiuses;
  radiuses.push_back(radius);
  radiuses.push_back(radius);
  radiuses.push_back(radius);
  std::vector<std::vector<int> > k_indices;
  std::vector<std::vector<float> > k_distances;
  int max_nn = -1;

  octree->radiusSearch (point, radiuses, k_indices,k_distances,max_nn );
}

#endif
TEST (PCL, Octree_Pointcloud_Neighbours_Within_Radius_Search)
{
  const unsigned int test_runs = 100;
  unsigned int test_id;

  // instantiate point clouds
  PointCloud<PointXYZ>::Ptr cloudIn (new PointCloud<PointXYZ> ());
  PointCloud<PointXYZ>::Ptr cloudOut (new PointCloud<PointXYZ> ());

  size_t i;

  srand (time (NULL));

  for (test_id = 0; test_id < test_runs; test_id++)
  {
    // define a random search point
    PointXYZ searchPoint (10.0 * ((double)rand () / (double)RAND_MAX), 10.0 * ((double)rand () / (double)RAND_MAX),
                          10.0 * ((double)rand () / (double)RAND_MAX));

    cloudIn->width = 1000;
    cloudIn->height = 1;
    cloudIn->points.resize (cloudIn->width * cloudIn->height);

    // generate point cloud data
    for (i = 0; i < 1000; i++)
    {
      cloudIn->points[i] = PointXYZ (10.0 * ((double)rand () / (double)RAND_MAX),
                                     10.0 * ((double)rand () / (double)RAND_MAX),
                                     5.0 * ((double)rand () / (double)RAND_MAX));
    }

    pcl::search::Search<PointXYZ>* octree = new pcl::search::Octree<PointXYZ> (0.001);

    // build octree
    double pointDist;
    double searchRadius = 5.0 * ((double)rand () / (double)RAND_MAX);

    // bruteforce radius search
    vector<int> cloudSearchBruteforce;
    for (i = 0; i < cloudIn->points.size (); i++)
    {
      pointDist = sqrt (
                        (cloudIn->points[i].x - searchPoint.x) * (cloudIn->points[i].x - searchPoint.x)
                            + (cloudIn->points[i].y - searchPoint.y) * (cloudIn->points[i].y - searchPoint.y)
                            + (cloudIn->points[i].z - searchPoint.z) * (cloudIn->points[i].z - searchPoint.z));

      if (pointDist <= searchRadius)
      {
        // add point candidates to vector list
        cloudSearchBruteforce.push_back ((int)i);
      }
    }

    vector<int> cloudNWRSearch;
    vector<float> cloudNWRRadius;

    // execute octree radius search
    octree->setInputCloud (cloudIn);
    octree->radiusSearch (searchPoint, searchRadius, cloudNWRSearch, cloudNWRRadius);

    ASSERT_EQ ( cloudNWRRadius.size() , cloudSearchBruteforce.size());

    // check if result from octree radius search can be also found in bruteforce search
    std::vector<int>::const_iterator current = cloudNWRSearch.begin();
    while (current != cloudNWRSearch.end())
    {
      pointDist = sqrt (
          (cloudIn->points[*current].x-searchPoint.x) * (cloudIn->points[*current].x-searchPoint.x) +
          (cloudIn->points[*current].y-searchPoint.y) * (cloudIn->points[*current].y-searchPoint.y) +
          (cloudIn->points[*current].z-searchPoint.z) * (cloudIn->points[*current].z-searchPoint.z)
      );

      ASSERT_EQ ( (pointDist<=searchRadius) , true);

      ++current;
    }

    // check if result limitation works
    octree->radiusSearch(searchPoint, searchRadius, cloudNWRSearch, cloudNWRRadius, 5);
    ASSERT_EQ ( cloudNWRRadius.size() <= 5, true);
  }
}

/* ---[ */
int
main (int argc, char** argv)
{
  testing::InitGoogleTest (&argc, argv);
  return (RUN_ALL_TESTS ());
}
/* ]--- */
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License or as specified alternatively below. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Major Contributor(s):
 * [ Copyright (C) 2011 Stephan Bergmann, Red Hat <sbergman@redhat.com> (initial
 *   developer) ]
 *
 * All Rights Reserved.
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */

#ifndef INCLUDED_SAL_LOG_HXX
#define INCLUDED_SAL_LOG_HXX

#include "sal/config.h"

#include <cstdlib>
#include <sstream>
#include <string>

#include "sal/detail/log.h"
#include "sal/types.h"

// Avoid the use of other sal code in this header as much as possible, so that
// this code can be called from other sal code without causing endless
// recursion.

/// @internal
extern "C" void SAL_CALL sal_detail_log(
    enum sal_detail_LogLevel level, char const * area, char const * where,
    char const * message);

/// @internal
namespace sal { namespace detail {

inline void SAL_CALL log(
    sal_detail_LogLevel level, char const * area, char const * where,
    std::ostringstream const & stream)
{
    // An alternative would be to have sal_detail_log take a std::ostringstream
    // pointer (via a C void pointer); the advantage would be smaller client
    // code (the ".str().c_str()" part would move into the implementation of
    // sal_detail_log) and potential for proper support of embedded null
    // characters within the message, but the disadvantage would be dependence
    // on the C++ ABI; as a compromise, the ".str().c_str()" part has been moved
    // to this inline function so that it is potentially only emitted once per
    // dynamic library:
    sal_detail_log(level, area, where, stream.str().c_str());
}

// Special handling of the common case where the message consists of just a
// string literal, to produce smaller call-site code:

struct StreamStart {};

struct StreamString {
    StreamString(char const * s): string(s) {}

    char const * string;

    typedef char Result;
};

struct StreamIgnore {
    typedef struct { char a[2]; } Result;
};

inline StreamString operator <<(StreamStart const &, char const * s) {
    return StreamString(s);
}

template< typename T > inline StreamIgnore operator <<(
    StreamStart const &, T const &)
{
    std::abort();
}

template< typename T > inline StreamIgnore operator <<(
    StreamString const &, T const &)
{
    std::abort();
}

template< typename T > inline StreamIgnore operator <<(
    StreamIgnore const &, T const &)
{
    std::abort();
}

template< typename T > typename T::Result getResult(T const &);

inline char const * unwrapStream(StreamString const & s) { return s.string; }

inline char const * unwrapStream(StreamIgnore const &) { std::abort(); }

} }

/// @internal
#define SAL_DETAIL_LOG_STREAM(condition, level, area, where, stream) \
    do { \
        if (condition) { \
            if (sizeof getResult(::sal::detail::StreamStart() << stream) == 1) \
            { \
                ::sal_detail_log( \
                    (level), (area), (where), \
                    ::sal::detail::unwrapStream( \
                        ::sal::detail::StreamStart() << stream)); \
            } else { \
                ::std::ostringstream sal_detail_stream; \
                sal_detail_stream << stream; \
                ::sal::detail::log( \
                    (level), (area), (where), sal_detail_stream); \
            } \
        } \
    } while (false)

/** A simple macro to create a "file and line number" string.

    Potentially not only useful within the log framework (where it is used
    automatically), but also when creating exception messages.

    @since LibreOffice 3.5
*/
#define SAL_WHERE SAL_DETAIL_WHERE

/** A facility for generating temporary string messages by piping items into a
    C++ std::ostringstream.

    This can be useful for example in a call to SAL_INFO when depending on some
    boolean condition data of incompatible types shall be streamed into the
    message, as in:

      SAL_INFO("foo", "object: " << (hasName ? obj->name : SAL_STREAM(obj)));

    @since LibreOffice 3.5
*/
#define SAL_STREAM(stream) \
    (dynamic_cast< ::std::ostringstream & >(::std::ostringstream() << stream). \
     str())

/** Basic logging functionality.

    SAL_INFO(char const * area, expr),
    SAL_INFO_IF(bool condition, char const * area, expr),
    SAL_WARN(char const * area, expr), and
    SAL_WARN_IF(bool condition, char const * area, expr) produce an info resp.
    warning log entry with a message produced by piping items into a C++
    std::ostringstream.  The given expr must be so that the full expression
    "stream << expr" is valid, where stream is a variable of type
    std::ostringstream.

      SAL_INFO("foo", "string " << s << " of length " << n)

    would be an example of such a call; if the given s is of type rtl::OUString,

      #include "rtl/oustringostreaminserter.hxx"

    would make sure that an appropriate operator << is available.

    In either case, the composed message should be in UTF-8 and it should
    contain no vertical formatting characters and no null characters

    For the _IF variants, log output is only generated if the given condition is
    true (in addition to the other conditions that have to be met).

    For all these macros, the given area argument must be non-null and must
    match the regular expression

      <area> ::= <segment>("."<segment>)*

    with

      <segment> ::= [0-9a-z]+

    Whether these macros generate any log output is controlled in a two-stage
    process.

    First, at compile time the macros SAL_LOG_INFO and SAL_LOG_WARN,
    respectively, control whether the INFO and WARN macros, respectively,
    expand to actual code (in case the macro is defined, to any value) or to
    no-ops (in case the macro is not defined).

    Second, at runtime the environment variable SAL_LOG further limits which
    macro calls actually generate log output.  The environment variable SAL_LOG
    must either be unset or must match the regular expression

      <env> ::= <switch>*

    with

      <switch> ::= <sense><level>("."<area>)?
      <sense> ::= "+"|"-"
      <level> ::= "INFO"|"WARN"

    If the environment variable is unset, "+WARN" is used instead (which results
    in all warnings being output but no infos).  If the given value does not
    match the regular expression, "+INFO+WARN" is used instead (which in turn
    results in everything being output).

    A given macro call's level (INFO or WARN) and area is matched against the
    given switches as follows:  Only those switches for which the level matches
    the given level and for which the area is a prefix (including both empty and
    full prefixes) of the given area are considered.  Log output is generated if
    and only if among the longest such switches (if any), there is at least one
    that has a sense of "+".  (That is, if both +INFO.foo and -INFO.foo are
    present, +INFO.foo wins.)

    For example, if SAL_LOG is "+INFO-INFO.foo+INFO.foo.bar", then calls like
    SAL_INFO("foo.bar", ...), SAL_INFO("foo.bar.baz", ...), or
    SAL_INFO("other", ...) generate output, while calls like
    SAL_INFO("foo", ...) or SAL_INFO("foo.barzzz", ...) do not.

    The generated log output consists of the given level ("info" or "warn"), the
    given area, the process ID, the thread ID, the source file, and the source
    line number, each followed by a colon, followed by a space, the given
    message, and a newline.  The precise format of the log output is subject to
    change.  The log output is printed to stderr without further text encoding
    conversion.

    @since LibreOffice 3.5
*/

#define SAL_INFO(area, stream) \
    SAL_DETAIL_LOG_STREAM( \
        SAL_DETAIL_ENABLE_LOG_INFO, ::SAL_DETAIL_LOG_LEVEL_INFO, area, \
        SAL_WHERE, stream)

#define SAL_INFO_IF(condition, area, stream)  \
    SAL_DETAIL_LOG_STREAM( \
        SAL_DETAIL_ENABLE_LOG_INFO && (condition), \
        ::SAL_DETAIL_LOG_LEVEL_INFO, area, SAL_WHERE, stream)

#define SAL_WARN(area, stream) \
    SAL_DETAIL_LOG_STREAM( \
        SAL_DETAIL_ENABLE_LOG_WARN, ::SAL_DETAIL_LOG_LEVEL_WARN, area, \
        SAL_WHERE, stream)

#define SAL_WARN_IF(condition, area, stream)   \
    SAL_DETAIL_LOG_STREAM( \
        SAL_DETAIL_ENABLE_LOG_WARN && (condition), \
        ::SAL_DETAIL_LOG_LEVEL_WARN, area, SAL_WHERE, stream)

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Silence bogus MSC "must return a value" errors.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License or as specified alternatively below. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Major Contributor(s):
 * [ Copyright (C) 2011 Stephan Bergmann, Red Hat <sbergman@redhat.com> (initial
 *   developer) ]
 *
 * All Rights Reserved.
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */

#ifndef INCLUDED_SAL_LOG_HXX
#define INCLUDED_SAL_LOG_HXX

#include "sal/config.h"

#include <cstdlib>
#include <sstream>
#include <string>

#include "sal/detail/log.h"
#include "sal/types.h"

// Avoid the use of other sal code in this header as much as possible, so that
// this code can be called from other sal code without causing endless
// recursion.

/// @internal
extern "C" void SAL_CALL sal_detail_log(
    enum sal_detail_LogLevel level, char const * area, char const * where,
    char const * message);

/// @internal
namespace sal { namespace detail {

inline void SAL_CALL log(
    sal_detail_LogLevel level, char const * area, char const * where,
    std::ostringstream const & stream)
{
    // An alternative would be to have sal_detail_log take a std::ostringstream
    // pointer (via a C void pointer); the advantage would be smaller client
    // code (the ".str().c_str()" part would move into the implementation of
    // sal_detail_log) and potential for proper support of embedded null
    // characters within the message, but the disadvantage would be dependence
    // on the C++ ABI; as a compromise, the ".str().c_str()" part has been moved
    // to this inline function so that it is potentially only emitted once per
    // dynamic library:
    sal_detail_log(level, area, where, stream.str().c_str());
}

// Special handling of the common case where the message consists of just a
// string literal, to produce smaller call-site code:

struct StreamStart {};

struct StreamString {
    StreamString(char const * s): string(s) {}

    char const * string;

    typedef char Result;
};

struct StreamIgnore {
    typedef struct { char a[2]; } Result;
};

inline StreamString operator <<(StreamStart const &, char const * s) {
    return StreamString(s);
}

template< typename T > inline StreamIgnore operator <<(
    StreamStart const &, T const &)
{
    std::abort();
#if defined _MSC_VER
    return StreamIgnore();
#endif
}

template< typename T > inline StreamIgnore operator <<(
    StreamString const &, T const &)
{
    std::abort();
#if defined _MSC_VER
    return StreamIgnore();
#endif
}

template< typename T > inline StreamIgnore operator <<(
    StreamIgnore const &, T const &)
{
    std::abort();
#if defined _MSC_VER
    return StreamIgnore();
#endif
}

template< typename T > typename T::Result getResult(T const &);

inline char const * unwrapStream(StreamString const & s) { return s.string; }

inline char const * unwrapStream(StreamIgnore const &) {
    std::abort();
#if defined _MSC_VER
    return 0;
#endif
}

} }

/// @internal
#define SAL_DETAIL_LOG_STREAM(condition, level, area, where, stream) \
    do { \
        if (condition) { \
            if (sizeof getResult(::sal::detail::StreamStart() << stream) == 1) \
            { \
                ::sal_detail_log( \
                    (level), (area), (where), \
                    ::sal::detail::unwrapStream( \
                        ::sal::detail::StreamStart() << stream)); \
            } else { \
                ::std::ostringstream sal_detail_stream; \
                sal_detail_stream << stream; \
                ::sal::detail::log( \
                    (level), (area), (where), sal_detail_stream); \
            } \
        } \
    } while (false)

/** A simple macro to create a "file and line number" string.

    Potentially not only useful within the log framework (where it is used
    automatically), but also when creating exception messages.

    @since LibreOffice 3.5
*/
#define SAL_WHERE SAL_DETAIL_WHERE

/** A facility for generating temporary string messages by piping items into a
    C++ std::ostringstream.

    This can be useful for example in a call to SAL_INFO when depending on some
    boolean condition data of incompatible types shall be streamed into the
    message, as in:

      SAL_INFO("foo", "object: " << (hasName ? obj->name : SAL_STREAM(obj)));

    @since LibreOffice 3.5
*/
#define SAL_STREAM(stream) \
    (dynamic_cast< ::std::ostringstream & >(::std::ostringstream() << stream). \
     str())

/** Basic logging functionality.

    SAL_INFO(char const * area, expr),
    SAL_INFO_IF(bool condition, char const * area, expr),
    SAL_WARN(char const * area, expr), and
    SAL_WARN_IF(bool condition, char const * area, expr) produce an info resp.
    warning log entry with a message produced by piping items into a C++
    std::ostringstream.  The given expr must be so that the full expression
    "stream << expr" is valid, where stream is a variable of type
    std::ostringstream.

      SAL_INFO("foo", "string " << s << " of length " << n)

    would be an example of such a call; if the given s is of type rtl::OUString,

      #include "rtl/oustringostreaminserter.hxx"

    would make sure that an appropriate operator << is available.

    In either case, the composed message should be in UTF-8 and it should
    contain no vertical formatting characters and no null characters

    For the _IF variants, log output is only generated if the given condition is
    true (in addition to the other conditions that have to be met).

    For all these macros, the given area argument must be non-null and must
    match the regular expression

      <area> ::= <segment>("."<segment>)*

    with

      <segment> ::= [0-9a-z]+

    Whether these macros generate any log output is controlled in a two-stage
    process.

    First, at compile time the macros SAL_LOG_INFO and SAL_LOG_WARN,
    respectively, control whether the INFO and WARN macros, respectively,
    expand to actual code (in case the macro is defined, to any value) or to
    no-ops (in case the macro is not defined).

    Second, at runtime the environment variable SAL_LOG further limits which
    macro calls actually generate log output.  The environment variable SAL_LOG
    must either be unset or must match the regular expression

      <env> ::= <switch>*

    with

      <switch> ::= <sense><level>("."<area>)?
      <sense> ::= "+"|"-"
      <level> ::= "INFO"|"WARN"

    If the environment variable is unset, "+WARN" is used instead (which results
    in all warnings being output but no infos).  If the given value does not
    match the regular expression, "+INFO+WARN" is used instead (which in turn
    results in everything being output).

    A given macro call's level (INFO or WARN) and area is matched against the
    given switches as follows:  Only those switches for which the level matches
    the given level and for which the area is a prefix (including both empty and
    full prefixes) of the given area are considered.  Log output is generated if
    and only if among the longest such switches (if any), there is at least one
    that has a sense of "+".  (That is, if both +INFO.foo and -INFO.foo are
    present, +INFO.foo wins.)

    For example, if SAL_LOG is "+INFO-INFO.foo+INFO.foo.bar", then calls like
    SAL_INFO("foo.bar", ...), SAL_INFO("foo.bar.baz", ...), or
    SAL_INFO("other", ...) generate output, while calls like
    SAL_INFO("foo", ...) or SAL_INFO("foo.barzzz", ...) do not.

    The generated log output consists of the given level ("info" or "warn"), the
    given area, the process ID, the thread ID, the source file, and the source
    line number, each followed by a colon, followed by a space, the given
    message, and a newline.  The precise format of the log output is subject to
    change.  The log output is printed to stderr without further text encoding
    conversion.

    @since LibreOffice 3.5
*/

#define SAL_INFO(area, stream) \
    SAL_DETAIL_LOG_STREAM( \
        SAL_DETAIL_ENABLE_LOG_INFO, ::SAL_DETAIL_LOG_LEVEL_INFO, area, \
        SAL_WHERE, stream)

#define SAL_INFO_IF(condition, area, stream)  \
    SAL_DETAIL_LOG_STREAM( \
        SAL_DETAIL_ENABLE_LOG_INFO && (condition), \
        ::SAL_DETAIL_LOG_LEVEL_INFO, area, SAL_WHERE, stream)

#define SAL_WARN(area, stream) \
    SAL_DETAIL_LOG_STREAM( \
        SAL_DETAIL_ENABLE_LOG_WARN, ::SAL_DETAIL_LOG_LEVEL_WARN, area, \
        SAL_WHERE, stream)

#define SAL_WARN_IF(condition, area, stream)   \
    SAL_DETAIL_LOG_STREAM( \
        SAL_DETAIL_ENABLE_LOG_WARN && (condition), \
        ::SAL_DETAIL_LOG_LEVEL_WARN, area, SAL_WHERE, stream)

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#ifdef WIN32
    #include <windows.h>
#else
    #include <sys/select.h>
    #include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>

#include "SaleaeDeviceApi.h"
#include "saleaeinterface.h"

#if 0
#include <iostream>
#include <typeinfo>
#define LOG std::cerr << "[" << __func__ << ":" << __LINE__ << "]"

typedef enum {
    UNKNOWN,
    LOGIC,
    LOGIC16
} SaleaeLogicInterfaceType;

struct SaleaeLogicUser {
    bool connected;
    bool error;
    SaleaeLogicInterfaceType type;
    LogicAnalyzerInterface *iface;
    SaleaeLogicUser() {
        connected = false;
        error = false;
        type = UNKNOWN;
        iface = NULL;
    }
};

static void cb_onconnect(U64 id, GenericInterface *iface, void *udata);
static void cb_ondisconnect(U64 id, void *udata);
static void cb_onreaddata(U64 id, U8 *data, U32 len, void *udata);
static void cb_onwritedata(U64 id, U8 *data, U32 len, void *udata);
static void cb_onerror(U64 id, void *udata);

void cb_onconnect(U64 id, GenericInterface *iface, void *udata)
{
    LOG << "Id: " << std::hex << id << std::dec << std::endl;
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    if (iface && lu) {
        lu->connected = true;
        lu->error = false;
        std::string iface_name = typeid(*iface).name();
        LOG << "Type: " << iface_name << std::endl;
        if (iface_name.find("Logic16Interface") != std::string::npos) {
            lu->type = LOGIC16;
            LOG << "this is a logic 16 device\n";
            Logic16Interface *l16 = dynamic_cast<Logic16Interface *>(iface);
            l16->RegisterOnReadData(cb_onreaddata, udata);
            l16->RegisterOnWriteData(cb_onwritedata, udata);
            l16->RegisterOnError(cb_onerror, udata);
            lu->iface = dynamic_cast<LogicAnalyzerInterface *>(iface);
            LOG << "Use 5.0V ? " << (l16->GetUse5Volts() ? "Y" : "N")
                << std::endl;
        } else if (iface_name.find("LogicInterface") != std::string::npos) {
            lu->type = LOGIC;
            LOG << "this is a logic device\n";
            LogicInterface *l8 = dynamic_cast<LogicInterface *>(iface);
            l8->RegisterOnReadData(cb_onreaddata, udata);
            l8->RegisterOnWriteData(cb_onwritedata, udata);
            l8->RegisterOnError(cb_onerror, udata);
            lu->iface = dynamic_cast<LogicAnalyzerInterface *>(iface);
        } else {
            lu->type = UNKNOWN;
            LOG << "this is an unknown or unsupported device\n";
            lu->iface = NULL;
            return;
        }
        if (lu->iface) {
            LOG << "USB 2.0: " << (lu->iface->IsUsb2pt0() ? "true" : "false")
                << std::endl;
            LOG << "Channel count: " << lu->iface->GetChannelCount()
                << std::endl;
            LOG << "Sample Rate: " << lu->iface->GetSampleRateHz() << " Hz\n";
            const U32 count= 16;
            U32 *buf = new U32[count];
            if (buf) {
                S32 rc = lu->iface->GetSupportedSampleRates(buf, count);
                LOG << "Available Sample Rates in Hz: [" << rc << "]\t";
                for (U32 i = 0; i < rc && rc > 0; ++i) {
                    std::cerr << buf[i] << ",";
                }
                std::cerr << std::endl;
                delete [] buf;
            }
        }
    }
}

void cb_ondisconnect(U64 id, void *udata)
{
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    LOG << "Id: " << std::hex << id << std::dec << std::endl;
    if (lu) {
        lu->connected = false;
    }
}

void cb_onreaddata(U64 id, U8 *data, U32 len, void *udata)
{
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    LOG << "Id: " << std::hex << id << std::dec << std::endl;

}

// seems to work only for Logic and not Logic16
void cb_onwritedata(U64 id, U8 *data, U32 len, void *udata)
{
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    LOG << "Id: " << std::hex << id << std::dec << std::endl;
}

void cb_onerror(U64 id, void *udata)
{
    LOG << "Id: " << std::hex << id << std::dec << std::endl;
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    if (lu) {
        lu->error = true;
        LOG << "Whoa! Error!!\n";
    }
}

#endif

saleaeinterface_t *saleaeinterface_new()
{
    saleaeinterface_t *obj = NULL;
    obj = (saleaeinterface_t *)malloc(sizeof(*obj));
    if (obj) {
        obj->itype = saleaeinterface_t::UNKNOWN;
        obj->ptr = NULL;
    } else {
        fprintf(stderr, "[%s:%d]Unable to allocate object\n",
                __func__, __LINE__);
    }
    return obj;
}

void saleaeinterface_DESTROY(saleaeinterface_t *obj)
{
    if (obj) {
        free(obj);
        obj = NULL;
    }
}

void saleaeinterface_begin_connect()
{
    DevicesManagerInterface::BeginConnect();
}

void saleaeinterface_register_on_connect(saleaeinterface_t *obj)
{
}

void saleaeinterface_register_on_disconnect(saleaeinterface_t *obj)
{
}

void saleaeinterface_register_on_readdata(saleaeinterface_t *obj)
{
}

void saleaeinterface_register_on_writedata(saleaeinterface_t *obj)
{
}

void saleaeinterface_register_on_error(saleaeinterface_t *obj)
{
}

#if 0
int main (int argc, char **argv)
{
    struct SaleaeLogicUser lu;
    struct timeval tv;
    DevicesManagerInterface::RegisterOnConnect(cb_onconnect, &lu);
    DevicesManagerInterface::RegisterOnDisconnect(cb_ondisconnect, &lu);
    DevicesManagerInterface::BeginConnect();
    LOG << "Please wait while we connect to the device...\n";
    tv.tv_sec = 2;
    tv.tv_usec = 0;
    while (select(0, NULL, NULL, NULL, &tv) != -1) {
        if (lu.error)
            break;
        tv.tv_sec = 2;
        tv.tv_usec = 0;
    }
    return 0;
}
#endif // 0
<commit_msg>logging for entering and exiting of a function<commit_after>#ifdef WIN32
    #include <windows.h>
    #ifndef __func__
        #define __func__ __FUNCTION__
    #endif
    #ifndef _CRT_SECURE_NO_WARNINGS
        #define _CRT_SECURE_NO_WARNINGS
    #endif
	#ifndef WIN32_LEAN_AND_MEAN
		#define WIN32_LEAN_AND_MEAN
	#endif
#else
    #include <sys/select.h>
    #include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>

#include "SaleaeDeviceApi.h"
#include "saleaeinterface.h"

#if 0
#include <iostream>
#include <typeinfo>
#define LOG std::cerr << "[" << __func__ << ":" << __LINE__ << "]"

typedef enum {
    UNKNOWN,
    LOGIC,
    LOGIC16
} SaleaeLogicInterfaceType;

struct SaleaeLogicUser {
    bool connected;
    bool error;
    SaleaeLogicInterfaceType type;
    LogicAnalyzerInterface *iface;
    SaleaeLogicUser() {
        connected = false;
        error = false;
        type = UNKNOWN;
        iface = NULL;
    }
};

static void cb_onconnect(U64 id, GenericInterface *iface, void *udata);
static void cb_ondisconnect(U64 id, void *udata);
static void cb_onreaddata(U64 id, U8 *data, U32 len, void *udata);
static void cb_onwritedata(U64 id, U8 *data, U32 len, void *udata);
static void cb_onerror(U64 id, void *udata);

void cb_onconnect(U64 id, GenericInterface *iface, void *udata)
{
    LOG << "Id: " << std::hex << id << std::dec << std::endl;
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    if (iface && lu) {
        lu->connected = true;
        lu->error = false;
        std::string iface_name = typeid(*iface).name();
        LOG << "Type: " << iface_name << std::endl;
        if (iface_name.find("Logic16Interface") != std::string::npos) {
            lu->type = LOGIC16;
            LOG << "this is a logic 16 device\n";
            Logic16Interface *l16 = dynamic_cast<Logic16Interface *>(iface);
            l16->RegisterOnReadData(cb_onreaddata, udata);
            l16->RegisterOnWriteData(cb_onwritedata, udata);
            l16->RegisterOnError(cb_onerror, udata);
            lu->iface = dynamic_cast<LogicAnalyzerInterface *>(iface);
            LOG << "Use 5.0V ? " << (l16->GetUse5Volts() ? "Y" : "N")
                << std::endl;
        } else if (iface_name.find("LogicInterface") != std::string::npos) {
            lu->type = LOGIC;
            LOG << "this is a logic device\n";
            LogicInterface *l8 = dynamic_cast<LogicInterface *>(iface);
            l8->RegisterOnReadData(cb_onreaddata, udata);
            l8->RegisterOnWriteData(cb_onwritedata, udata);
            l8->RegisterOnError(cb_onerror, udata);
            lu->iface = dynamic_cast<LogicAnalyzerInterface *>(iface);
        } else {
            lu->type = UNKNOWN;
            LOG << "this is an unknown or unsupported device\n";
            lu->iface = NULL;
            return;
        }
        if (lu->iface) {
            LOG << "USB 2.0: " << (lu->iface->IsUsb2pt0() ? "true" : "false")
                << std::endl;
            LOG << "Channel count: " << lu->iface->GetChannelCount()
                << std::endl;
            LOG << "Sample Rate: " << lu->iface->GetSampleRateHz() << " Hz\n";
            const U32 count= 16;
            U32 *buf = new U32[count];
            if (buf) {
                S32 rc = lu->iface->GetSupportedSampleRates(buf, count);
                LOG << "Available Sample Rates in Hz: [" << rc << "]\t";
                for (U32 i = 0; i < rc && rc > 0; ++i) {
                    std::cerr << buf[i] << ",";
                }
                std::cerr << std::endl;
                delete [] buf;
            }
        }
    }
}

void cb_ondisconnect(U64 id, void *udata)
{
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    LOG << "Id: " << std::hex << id << std::dec << std::endl;
    if (lu) {
        lu->connected = false;
    }
}

void cb_onreaddata(U64 id, U8 *data, U32 len, void *udata)
{
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    LOG << "Id: " << std::hex << id << std::dec << std::endl;

}

// seems to work only for Logic and not Logic16
void cb_onwritedata(U64 id, U8 *data, U32 len, void *udata)
{
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    LOG << "Id: " << std::hex << id << std::dec << std::endl;
}

void cb_onerror(U64 id, void *udata)
{
    LOG << "Id: " << std::hex << id << std::dec << std::endl;
    struct SaleaeLogicUser *lu = (struct SaleaeLogicUser *)udata;
    if (lu) {
        lu->error = true;
        LOG << "Whoa! Error!!\n";
    }
}

#endif

#define IAMHERE1 fprintf(stderr, "[%s:%d] Entering\n", __func__, __LINE__)
#define IAMHERE2 fprintf(stderr, "[%s:%d] Exiting\n", __func__, __LINE__)

saleaeinterface_t *saleaeinterface_new()
{
    saleaeinterface_t *obj = NULL;
    IAMHERE1;
    obj = (saleaeinterface_t *)malloc(sizeof(*obj));
    if (obj) {
        obj->itype = saleaeinterface_t::UNKNOWN;
        obj->ptr = NULL;
    } else {
        fprintf(stderr, "[%s:%d]Unable to allocate object\n",
                __func__, __LINE__);
    }
    IAMHERE2;
    return obj;
}

void saleaeinterface_DESTROY(saleaeinterface_t *obj)
{
    IAMHERE1;
    if (obj) {
        free(obj);
        obj = NULL;
    }
    IAMHERE2;
}

void saleaeinterface_begin_connect()
{
    IAMHERE1;
    DevicesManagerInterface::BeginConnect();
    IAMHERE2;
}

void saleaeinterface_register_on_connect(saleaeinterface_t *obj)
{
}

void saleaeinterface_register_on_disconnect(saleaeinterface_t *obj)
{
}

void saleaeinterface_register_on_readdata(saleaeinterface_t *obj)
{
}

void saleaeinterface_register_on_writedata(saleaeinterface_t *obj)
{
}

void saleaeinterface_register_on_error(saleaeinterface_t *obj)
{
}

#if 0
int main (int argc, char **argv)
{
    struct SaleaeLogicUser lu;
    struct timeval tv;
    DevicesManagerInterface::RegisterOnConnect(cb_onconnect, &lu);
    DevicesManagerInterface::RegisterOnDisconnect(cb_ondisconnect, &lu);
    DevicesManagerInterface::BeginConnect();
    LOG << "Please wait while we connect to the device...\n";
    tv.tv_sec = 2;
    tv.tv_usec = 0;
    while (select(0, NULL, NULL, NULL, &tv) != -1) {
        if (lu.error)
            break;
        tv.tv_sec = 2;
        tv.tv_usec = 0;
    }
    return 0;
}
#endif // 0
<|endoftext|>


<commit_before>/*
This file is part of Groho, a simulator for inter-planetary travel and warfare.
Copyright (c) 2017-2018 by Kaushik Ghose. Some rights reserved, see LICENSE

This file defines the simulator code
*/
#include <filesystem>

#include "initialorbit.hpp"
#include "simulation.hpp"
#include "simulator.hpp"

#define LOGURU_WITH_STREAMS 1
#include "loguru.hpp"

namespace groho {

void initialize_ships(Simulation& simulation)
{
    auto& pos = simulation.state.spacecraft.pos();
    auto& vel = simulation.state.spacecraft.vel();
    for (size_t i = 0; i < pos.size(); i++) {
        set_initial_orbit(
            simulation.scenario.spacecraft_tokens[i].initial_condition,
            simulation.state,
            simulation.orrery,
            pos[i],
            vel[i]);
    }
}

void update_ship_state(double t, const double dt, State& state)
{
    auto& pos = state.spacecraft.pos();
    auto& vel = state.spacecraft.vel();
    auto& acc = state.spacecraft.acc();

    for (size_t i = 0; i < pos.size(); i++) {
        pos[i].t = t;
        pos[i] += vel[i] * dt;
        vel[i] += acc[i] * dt;
    }
}

void compute_gravitational_acceleration(
    const State& state, const Orrery& orrery, v3d_vec_t& ship_acc)
{
    const auto& ship_pos   = state.spacecraft.pos();
    const auto& orrery_pos = state.orrery.pos();

    for (size_t i = 0; i < ship_pos.size(); i++) {
        ship_acc[i] = { 0, 0, 0 };
        for (size_t g_idx : orrery.grav_body_idx) {
            auto r = orrery_pos[g_idx] - ship_pos[i];
            auto f = orrery.bodies[g_idx].GM / r.norm_sq();
            ship_acc[i] += r.normed() * f;
        }
    }
}

void add_thrust_to_acceleration(
    const State&            state,
    const Serialize&        solar_system,
    const SpacecraftTokens& spacecraft_tokens,
    v3d_vec_t&              ship_acc)
{
}

Simulator::Simulator(std::string scn_file, std::string outdir)
{
    auto lines = load_input_file(scn_file);
    if (!lines) {
        return;
    }

    Scenario   scenario(*lines);
    Simulation simulation(scenario, outdir);

    const auto& sim = scenario.sim;
    LOG_S(INFO) << "start: " << sim.begin.as_ut();
    LOG_S(INFO) << "end:   " << sim.end.as_ut();
    LOG_S(INFO) << "step:  " << sim.dt;

    auto& state = simulation.state;

    double t     = sim.begin;
    size_t steps = 0;

    if (simulation.requires_state_initialization()) {
        // Warm up
        for (size_t i = 0; i < 4; i++, steps++) {
            simulation.orrery.pos_at(t, state.orrery.next_pos());
            simulation.solar_system.append(state.orrery.pos());
            t += sim.dt;
        }

        // Initialize ships state
        initialize_ships(simulation);
    }

    // Main sim
    for (; t < sim.end; t += sim.dt, steps++) {
        simulation.orrery.pos_at(t, state.orrery.next_pos());
        update_ship_state(t, sim.dt, state);
        compute_gravitational_acceleration(
            state, simulation.orrery, state.spacecraft.acc());
        add_thrust_to_acceleration(
            state,
            simulation.solar_system,
            simulation.scenario.spacecraft_tokens,
            state.spacecraft.acc());

        simulation.solar_system.append(state.orrery.pos());
        simulation.spacecraft.append(state.spacecraft.pos());
    }
    simulation.solar_system.flush(state.orrery.pos());
    simulation.spacecraft.flush(state.spacecraft.pos());
    LOG_S(INFO) << steps << " steps";
}

}<commit_msg>Not quite leap-frog integration, but it will do<commit_after>/*
This file is part of Groho, a simulator for inter-planetary travel and warfare.
Copyright (c) 2017-2018 by Kaushik Ghose. Some rights reserved, see LICENSE

This file defines the simulator code
*/
#include <filesystem>

#include "initialorbit.hpp"
#include "simulation.hpp"
#include "simulator.hpp"

#define LOGURU_WITH_STREAMS 1
#include "loguru.hpp"

namespace groho {

void initialize_ships(Simulation& simulation)
{
    auto& pos = simulation.state.spacecraft.pos();
    auto& vel = simulation.state.spacecraft.vel();
    for (size_t i = 0; i < pos.size(); i++) {
        set_initial_orbit(
            simulation.scenario.spacecraft_tokens[i].initial_condition,
            simulation.state,
            simulation.orrery,
            pos[i],
            vel[i]);
    }
}

void update_ship_state(double t, const double dt, State& state)
{
    auto& pos = state.spacecraft.pos();
    auto& vel = state.spacecraft.vel();
    auto& acc = state.spacecraft.acc();

    for (size_t i = 0; i < pos.size(); i++) {
        vel[i] += acc[i] * dt;
        pos[i] += vel[i] * dt;
        pos[i].t = t;
    }
}

void compute_gravitational_acceleration(
    const State& state, const Orrery& orrery, v3d_vec_t& ship_acc)
{
    const auto& ship_pos   = state.spacecraft.pos();
    const auto& orrery_pos = state.orrery.pos();

    for (size_t i = 0; i < ship_pos.size(); i++) {
        ship_acc[i] = { 0, 0, 0 };
        for (size_t g_idx : orrery.grav_body_idx) {
            auto r = orrery_pos[g_idx] - ship_pos[i];
            auto f = orrery.bodies[g_idx].GM / r.norm_sq();
            ship_acc[i] += r.normed() * f;
        }
    }
}

void add_thrust_to_acceleration(
    const State&            state,
    const Serialize&        solar_system,
    const SpacecraftTokens& spacecraft_tokens,
    v3d_vec_t&              ship_acc)
{
}

Simulator::Simulator(std::string scn_file, std::string outdir)
{
    auto lines = load_input_file(scn_file);
    if (!lines) {
        return;
    }

    Scenario   scenario(*lines);
    Simulation simulation(scenario, outdir);

    const auto& sim = scenario.sim;
    LOG_S(INFO) << "start: " << sim.begin.as_ut();
    LOG_S(INFO) << "end:   " << sim.end.as_ut();
    LOG_S(INFO) << "step:  " << sim.dt;

    auto& state = simulation.state;

    double t     = sim.begin;
    size_t steps = 0;

    if (simulation.requires_state_initialization()) {
        // Warm up
        for (size_t i = 0; i < 4; i++, steps++) {
            simulation.orrery.pos_at(t, state.orrery.next_pos());
            simulation.solar_system.append(state.orrery.pos());
            t += sim.dt;
        }

        // Initialize ships state
        initialize_ships(simulation);
    }

    // Main sim
    for (; t < sim.end; t += sim.dt, steps++) {
        simulation.orrery.pos_at(t, state.orrery.next_pos());
        update_ship_state(t, sim.dt, state);
        compute_gravitational_acceleration(
            state, simulation.orrery, state.spacecraft.acc());
        add_thrust_to_acceleration(
            state,
            simulation.solar_system,
            simulation.scenario.spacecraft_tokens,
            state.spacecraft.acc());

        simulation.solar_system.append(state.orrery.pos());
        simulation.spacecraft.append(state.spacecraft.pos());
    }
    simulation.solar_system.flush(state.orrery.pos());
    simulation.spacecraft.flush(state.spacecraft.pos());
    LOG_S(INFO) << steps << " steps";
}

}<|endoftext|>


<commit_before>// Copyright (c) 2014 Steinwurf ApS
// All Rights Reserved
//
// Distributed under the "BSD License". See the accompanying LICENSE.rst file.

namespace stub
{
    /// @brief The return_handler is a helper object that is used
    /// e.g. in the call object to control which return values should
    /// be generated when called.
    ///
    /// The return_handler provides the call operator() and when
    /// invoked it will return the specified return value. The type R
    /// will be the return value.
    ///
    /// Example:
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_return(4U);
    ///
    ///    uint32_t a = v();
    ///    assert(a == 4U);
    ///
    ///    uint32_t b = v();
    ///    assert(b == 4U);
    ///
    ///    uint32_t c = v();
    ///    assert(c != 3U);
    ///    assert(c == 4U);
    ///
    /// Or alternatively using the set_returns() function:
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_returns({4U,3U});
    ///
    ///    uint32_t a = v();
    ///    assert(a == 4U);
    ///
    ///    uint32_t b = v();
    ///    assert(b == 3U);
    ///
    ///    uint32_t c = v();
    ///    assert(c == 4U);
    ///
    ///    uint32_t d = v();
    ///    assert(d != 4U);
    ///    assert(d == 3U);
    ///
    /// The default behavior is to repeat the specified return values i.e.:
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_return(3U);
    ///
    ///    uint32_t a = v();
    ///    uint32_t b = v();
    ///    uint32_t c = v();
    ///
    ///    assert(a == 3U && b == 3U && c == 3U);
    ///
    /// This behavior can be change by calling no_repeat() in which
    /// case the return_handler can only be invoked once per return
    /// value specified:
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_return(1U).no_repeat();
    ///
    ///    uint32_t a = v();
    ///    uint32_t b = v(); // <---- Crash
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_return({1U,2U,3U}).no_repeat();
    ///
    ///    uint32_t a = v();
    ///    uint32_t b = v();
    ///    uint32_t c = v();
    ///    uint32_t d = v(); // <---- Crash
    ///
    template<class R>
    class return_handler
    {
    public:

        /// Constructor
        return_handler()
            : m_repeat(true),
              m_position(0)
        { }

        /// Initializes the return_handler with one specific return
        /// value. Calling this function will also reset the
        /// return_handler state. So any previously specified returns
        /// values will be removed etc.
        ///
        /// @param values The return value to use
        ///
        /// @return Reference to the return handler, this allows the
        /// caller to perform additional customization to the return
        /// handler such as turn on or off repeat.
        return_handler& set_return(const R& value)
        {
            m_repeat = true;
            m_position = 0;
            m_returns.clear();

            m_returns = {value};

            return *this;
        }

        /// Initializes the return_handler with the return values to
        /// use. Calling this function will also reset the
        /// return_handler state. So any previously specified returns
        /// values will be removed etc.
        ///
        /// @param values The list of return values to use
        ///
        /// @return Reference to the return handler, this allows the
        /// caller to perform additional customization to the return
        /// handler such as turn on or off repeat.
        return_handler& set_return(const std::initializer_list<R>& values)
        {
            m_repeat = true;
            m_position = 0;
            m_returns.clear();

            m_returns = values;

            return *this;
        }

        /// Set repeat off. This means that no values will be repeated
        /// the user has to specify exactly the number of values that
        /// should be return otherwise an assert will be triggered.
        void no_repeat()
        {
            m_repeat = false;
        }

        /// The call operator which will generate a return value.
        /// @return The generated return value
        R operator()() const
        {
            // If we are repeating and we have reached the end of the
            // list of return values
            if (m_repeat && (m_position == m_returns.size()))
                m_position = 0;

            assert(m_position < m_returns.size());

            R value = m_returns[m_position];
            ++m_position;

            return value;
        }

    private:

        /// Boolean value controlling whether we should repeat return
        /// values when reaching the end of the return value vector or
        /// assert. True means we repeat, false means we should assert.
        bool m_repeat;

        /// The position of the return values vector that we will
        /// return upon next invocation of the call operator. The
        /// m_positions is mutable since the call operator is a const
        /// function and we need to increment m_positions once called.
        mutable uint32_t m_position;

        /// Vector storing the return values to be used.
        std::vector<R> m_returns;
    };

    /// Specialization for the case of a void function i.e. no return
    /// value. We expect no calls to this return_handler the call
    /// operator is only there to allow the code to compile when
    /// e.g. the call class instantiates a return handler.
    template<>
    class return_handler<void>
    {
    public:

        /// Empty call operator
        void operator()() const
        { }
    };
}
<commit_msg>Adding missing includes<commit_after>// Copyright (c) 2014 Steinwurf ApS
// All Rights Reserved
//
// Distributed under the "BSD License". See the accompanying LICENSE.rst file.

#include <cstdint>
#include <cassert>

namespace stub
{
    /// @brief The return_handler is a helper object that is used
    /// e.g. in the call object to control which return values should
    /// be generated when called.
    ///
    /// The return_handler provides the call operator() and when
    /// invoked it will return the specified return value. The type R
    /// will be the return value.
    ///
    /// Example:
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_return(4U);
    ///
    ///    uint32_t a = v();
    ///    assert(a == 4U);
    ///
    ///    uint32_t b = v();
    ///    assert(b == 4U);
    ///
    ///    uint32_t c = v();
    ///    assert(c != 3U);
    ///    assert(c == 4U);
    ///
    /// Or alternatively using the set_returns() function:
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_returns({4U,3U});
    ///
    ///    uint32_t a = v();
    ///    assert(a == 4U);
    ///
    ///    uint32_t b = v();
    ///    assert(b == 3U);
    ///
    ///    uint32_t c = v();
    ///    assert(c == 4U);
    ///
    ///    uint32_t d = v();
    ///    assert(d != 4U);
    ///    assert(d == 3U);
    ///
    /// The default behavior is to repeat the specified return values i.e.:
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_return(3U);
    ///
    ///    uint32_t a = v();
    ///    uint32_t b = v();
    ///    uint32_t c = v();
    ///
    ///    assert(a == 3U && b == 3U && c == 3U);
    ///
    /// This behavior can be change by calling no_repeat() in which
    /// case the return_handler can only be invoked once per return
    /// value specified:
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_return(1U).no_repeat();
    ///
    ///    uint32_t a = v();
    ///    uint32_t b = v(); // <---- Crash
    ///
    ///    return_handler<uint32_t> v;
    ///    v.set_return({1U,2U,3U}).no_repeat();
    ///
    ///    uint32_t a = v();
    ///    uint32_t b = v();
    ///    uint32_t c = v();
    ///    uint32_t d = v(); // <---- Crash
    ///
    template<class R>
    class return_handler
    {
    public:

        /// Constructor
        return_handler()
            : m_repeat(true),
              m_position(0)
        { }

        /// Initializes the return_handler with one specific return
        /// value. Calling this function will also reset the
        /// return_handler state. So any previously specified returns
        /// values will be removed etc.
        ///
        /// @param values The return value to use
        ///
        /// @return Reference to the return handler, this allows the
        /// caller to perform additional customization to the return
        /// handler such as turn on or off repeat.
        return_handler& set_return(const R& value)
        {
            m_repeat = true;
            m_position = 0;
            m_returns.clear();

            m_returns = {value};

            return *this;
        }

        /// Initializes the return_handler with the return values to
        /// use. Calling this function will also reset the
        /// return_handler state. So any previously specified returns
        /// values will be removed etc.
        ///
        /// @param values The list of return values to use
        ///
        /// @return Reference to the return handler, this allows the
        /// caller to perform additional customization to the return
        /// handler such as turn on or off repeat.
        return_handler& set_return(const std::initializer_list<R>& values)
        {
            m_repeat = true;
            m_position = 0;
            m_returns.clear();

            m_returns = values;

            return *this;
        }

        /// Set repeat off. This means that no values will be repeated
        /// the user has to specify exactly the number of values that
        /// should be return otherwise an assert will be triggered.
        void no_repeat()
        {
            m_repeat = false;
        }

        /// The call operator which will generate a return value.
        /// @return The generated return value
        R operator()() const
        {
            // If we are repeating and we have reached the end of the
            // list of return values
            if (m_repeat && (m_position == m_returns.size()))
                m_position = 0;

            assert(m_position < m_returns.size());

            R value = m_returns[m_position];
            ++m_position;

            return value;
        }

    private:

        /// Boolean value controlling whether we should repeat return
        /// values when reaching the end of the return value vector or
        /// assert. True means we repeat, false means we should assert.
        bool m_repeat;

        /// The position of the return values vector that we will
        /// return upon next invocation of the call operator. The
        /// m_positions is mutable since the call operator is a const
        /// function and we need to increment m_positions once called.
        mutable uint32_t m_position;

        /// Vector storing the return values to be used.
        std::vector<R> m_returns;
    };

    /// Specialization for the case of a void function i.e. no return
    /// value. We expect no calls to this return_handler the call
    /// operator is only there to allow the code to compile when
    /// e.g. the call class instantiates a return handler.
    template<>
    class return_handler<void>
    {
    public:

        /// Empty call operator
        void operator()() const
        { }
    };
}
<|endoftext|>


<commit_before>/*******************************************************************************
 * c7a/api/action_node.hpp
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_API_ACTION_NODE_HEADER
#define C7A_API_ACTION_NODE_HEADER

#include "dia_node.hpp"
#include <c7a/core/stage_builder.hpp>

namespace c7a {

template <typename T>
class ActionNode : public DIANode<T>
{
public:
    ActionNode(Context& ctx,
               const DIABaseVector& parents)
        : DIANode<T>(ctx, parents) { }

    virtual ~ActionNode() { }
};

} // namespace c7a

#endif // !C7A_API_ACTION_NODE_HEADER

/******************************************************************************/
<commit_msg>add virtual function result()<commit_after>/*******************************************************************************
 * c7a/api/action_node.hpp
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_API_ACTION_NODE_HEADER
#define C7A_API_ACTION_NODE_HEADER

#include "dia_node.hpp"
#include <c7a/core/stage_builder.hpp>

namespace c7a {

template <typename T>
class ActionNode : public DIANode<T>
{
public:
    ActionNode(Context& ctx,
               const DIABaseVector& parents)
        : DIANode<T>(ctx, parents) { }

    virtual ~ActionNode() { }

    virtual auto result() { }
};

} // namespace c7a

#endif // !C7A_API_ACTION_NODE_HEADER

/******************************************************************************/
<|endoftext|>


<commit_before>#include <QUrl>
#include "qt_sound.hpp"

QtSound::QtSound() {
  for (auto &kv : sound_map) {
    auto path = QUrl::fromLocalFile(kv.second.first);
    sounds[kv.first].setSource(path);
  }
}

bool QtSound::play(AudibleAlert alert) {
  int loops = sound_map[alert].second> - 1 ? sound_map[alert].second : QSoundEffect::Infinite;
  sounds[alert].setLoopCount(loops);
  sounds[alert].setVolume(0.7);
  sounds[alert].play();
  return true;
}

void QtSound::stop() {
  for (auto &kv : sounds) {
    // Only stop repeating sounds
    if (sound_map[kv.first].second != 0) {
      kv.second.stop();
    }
  }
}

void QtSound::setVolume(int volume) {
  // TODO: implement this
}
<commit_msg>qt_sound: lower volume<commit_after>#include <QUrl>
#include "qt_sound.hpp"

QtSound::QtSound() {
  for (auto &kv : sound_map) {
    auto path = QUrl::fromLocalFile(kv.second.first);
    sounds[kv.first].setSource(path);
  }
}

bool QtSound::play(AudibleAlert alert) {
  int loops = sound_map[alert].second> - 1 ? sound_map[alert].second : QSoundEffect::Infinite;
  sounds[alert].setLoopCount(loops);
  sounds[alert].setVolume(0.45);
  sounds[alert].play();
  return true;
}

void QtSound::stop() {
  for (auto &kv : sounds) {
    // Only stop repeating sounds
    if (sound_map[kv.first].second != 0) {
      kv.second.stop();
    }
  }
}

void QtSound::setVolume(int volume) {
  // TODO: implement this
}
<|endoftext|>


<commit_before>#pragma once

#ifdef __clang__
#pragma GCC diagnostic ignored "-Wdeprecated"
#pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
#pragma GCC diagnostic ignored "-Wdocumentation"
#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wextra-semi"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wreserved-id-macro"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wundef"
#pragma GCC diagnostic ignored "-Wunused-parameter"
// #pragma GCC diagnostic ignored "-Wexit-time-destructors"
#endif

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>bug fix<commit_after>// No pragma once!!

#ifdef __clang__
#pragma GCC diagnostic ignored "-Wdeprecated"
#pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
#pragma GCC diagnostic ignored "-Wdocumentation"
#pragma GCC diagnostic ignored "-Wdocumentation-unknown-command"
#pragma GCC diagnostic ignored "-Wglobal-constructors"
#pragma GCC diagnostic ignored "-Wextra-semi"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wreserved-id-macro"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wundef"
#pragma GCC diagnostic ignored "-Wunused-parameter"
// #pragma GCC diagnostic ignored "-Wexit-time-destructors"
#endif

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>