<commit_before>/************************************************************************/
/*                                                                      */
/*               Copyright 1998-2000 by Ullrich Koethe                  */
/*       Cognitive Systems Group, University of Hamburg, Germany        */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    You may use, modify, and distribute this software according       */
/*    to the terms stated in the LICENSE file included in               */
/*    the VIGRA distribution.                                           */
/*                                                                      */
/*    The VIGRA Website is                                              */
/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
/*    Please direct questions, bug reports, and contributions to        */
/*        koethe@informatik.uni-hamburg.de                              */
/*                                                                      */
/*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
/*                                                                      */
/************************************************************************/

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%  This file contains source code adapted from ImageMagick                    %
%                                                                             %
%  ImageMagick is Copyright 1998 E. I. du Pont de Nemours and Company         %
%                                                                             %
%  Permission is hereby granted, free of charge, to any person obtaining a    %
%  copy of this software and associated documentation files ("ImageMagick"),  %
%  to deal in ImageMagick without restriction, including without limitation   %
%  the rights to use, copy, modify, merge, publish, distribute, sublicense,   %
%  and/or sell copies of ImageMagick, and to permit persons to whom the       %
%  ImageMagick is furnished to do so, subject to the following conditions:    %
%                                                                             %
%  The above copyright notice and this permission notice shall be included in %
%  all copies or substantial portions of ImageMagick.                         %
%                                                                             %
%  The software is provided "as is", without warranty of any kind, express or %
%  implied, including but not limited to the warranties of merchantability,   %
%  fitness for a particular purpose and noninfringement.  In no event shall   %
%  E. I. du Pont de Nemours and Company be liable for any claim, damages or   %
%  other liability, whether in an action of contract, tort or otherwise,      %
%  arising from, out of or in connection with ImageMagick or the use or other %
%  dealings in ImageMagick.                                                   %
%                                                                             %
%  Except as contained in this notice, the name of the E. I. du Pont de       %
%  Nemours and Company shall not be used in advertising or otherwise to       %
%  promote the sale, use or other dealings in ImageMagick without prior       %
%  written authorization from the E. I. du Pont de Nemours and Company.       %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#if !defined(HasTIFF)

#include "vigra/error.hxx"
#include "vigra/tiff.h"

Export VigraImpexImage *vigraImpexReadTIFFImage( VigraImpexImageInfo *image_info)
{
  fail( "TIFF library is not available");
  return 0;
}
Export unsigned int vigraImpexWriteTIFFImage( VigraImpexImageInfo *image_info,VigraImpexImage *image)
{
  fail( "TIFF library is not available");
  return 0;
}
Export	void TIFFClose(TiffImage*)
{
  fail( "TIFF library is not available");
}
Export	TiffImage* TIFFOpen(const char*, const char*)
{
  fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFGetField(TiffImage*, ttag_t, ...)
{
  fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFSetField(TiffImage*, ttag_t, ...)
{
  fail( "TIFF library is not available");
  return 0;
}
Export	tsize_t TIFFScanlineSize(TiffImage*)
{
  fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFReadScanline(TiffImage*, tdata_t, uint32, tsample_t = 0)
{
  fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFWriteScanline(TiffImage*, tdata_t, uint32, tsample_t = 0)
{
  fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFReadRGBAImage(TiffImage*, uint32, uint32, uint32*, int = 0)
{
  fail( "TIFF library is not available");
  return 0;
}
#endif
<commit_msg>added missing include and changed "fail()" into "vigra_fail()" in order to make the file work when HasTiff is not defined.<commit_after>/************************************************************************/
/*                                                                      */
/*               Copyright 1998-2000 by Ullrich Koethe                  */
/*       Cognitive Systems Group, University of Hamburg, Germany        */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    ( Version 1.1.0, Dec 05 2000 )                                    */
/*    You may use, modify, and distribute this software according       */
/*    to the terms stated in the LICENSE file included in               */
/*    the VIGRA distribution.                                           */
/*                                                                      */
/*    The VIGRA Website is                                              */
/*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
/*    Please direct questions, bug reports, and contributions to        */
/*        koethe@informatik.uni-hamburg.de                              */
/*                                                                      */
/*  THIS SOFTWARE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR          */
/*  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED      */
/*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */
/*                                                                      */
/************************************************************************/

/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%  This file contains source code adapted from ImageMagick                    %
%                                                                             %
%  ImageMagick is Copyright 1998 E. I. du Pont de Nemours and Company         %
%                                                                             %
%  Permission is hereby granted, free of charge, to any person obtaining a    %
%  copy of this software and associated documentation files ("ImageMagick"),  %
%  to deal in ImageMagick without restriction, including without limitation   %
%  the rights to use, copy, modify, merge, publish, distribute, sublicense,   %
%  and/or sell copies of ImageMagick, and to permit persons to whom the       %
%  ImageMagick is furnished to do so, subject to the following conditions:    %
%                                                                             %
%  The above copyright notice and this permission notice shall be included in %
%  all copies or substantial portions of ImageMagick.                         %
%                                                                             %
%  The software is provided "as is", without warranty of any kind, express or %
%  implied, including but not limited to the warranties of merchantability,   %
%  fitness for a particular purpose and noninfringement.  In no event shall   %
%  E. I. du Pont de Nemours and Company be liable for any claim, damages or   %
%  other liability, whether in an action of contract, tort or otherwise,      %
%  arising from, out of or in connection with ImageMagick or the use or other %
%  dealings in ImageMagick.                                                   %
%                                                                             %
%  Except as contained in this notice, the name of the E. I. du Pont de       %
%  Nemours and Company shall not be used in advertising or otherwise to       %
%  promote the sale, use or other dealings in ImageMagick without prior       %
%  written authorization from the E. I. du Pont de Nemours and Company.       %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#if !defined(HasTIFF)

#include "vigra/error.hxx"
#include "vigra/tiff.h"
#include "vigra/impex.h"

Export VigraImpexImage *vigraImpexReadTIFFImage( VigraImpexImageInfo *image_info)
{
  vigra_fail( "TIFF library is not available");
  return 0;
}
Export unsigned int vigraImpexWriteTIFFImage( VigraImpexImageInfo *image_info,VigraImpexImage *image)
{
  vigra_fail( "TIFF library is not available");
  return 0;
}
Export	void TIFFClose(TiffImage*)
{
  vigra_fail( "TIFF library is not available");
}
Export	TiffImage* TIFFOpen(const char*, const char*)
{
  vigra_fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFGetField(TiffImage*, ttag_t, ...)
{
  vigra_fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFSetField(TiffImage*, ttag_t, ...)
{
  vigra_fail( "TIFF library is not available");
  return 0;
}
Export	tsize_t TIFFScanlineSize(TiffImage*)
{
  vigra_fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFReadScanline(TiffImage*, tdata_t, uint32, tsample_t = 0)
{
  vigra_fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFWriteScanline(TiffImage*, tdata_t, uint32, tsample_t = 0)
{
  vigra_fail( "TIFF library is not available");
  return 0;
}
Export	int TIFFReadRGBAImage(TiffImage*, uint32, uint32, uint32*, int = 0)
{
  vigra_fail( "TIFF library is not available");
  return 0;
}
#endif
<|endoftext|>


<commit_before>#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

#include <numpy/arrayobject.h>

#include <omp.h>
#include <stdio.h>

#include <complex>

#include <boost/preprocessor/repetition/repeat.hpp>

#include "atomic_add.hpp"

template <typename DTYPE, typename ITYPE>
void sparse_matvec_template(PyArrayObject* inp, PyArrayObject* outp, npy_intp zsize, PyArrayObject* dz, PyArrayObject* bounds, PyArrayObject* col, PyArrayObject* row, PyArrayObject* coeff, int threads)
{

	PyArrayObject* ops[3] = {col, row, coeff};
	npy_uint32 flags = NPY_ITER_EXTERNAL_LOOP|NPY_ITER_GROWINNER|NPY_ITER_RANGED|NPY_ITER_BUFFERED|NPY_ITER_DELAY_BUFALLOC;
	npy_uint32 op_flags[3] = {NPY_ITER_READONLY, NPY_ITER_READONLY, NPY_ITER_READONLY};
	NpyIter* iter = NpyIter_MultiNew(3, ops , flags, NPY_KEEPORDER, NPY_NO_CASTING, op_flags, NULL);

	npy_intp dz_size = PyArray_SIZE(dz);
	npy_intp inp_zstride = PyArray_SIZE(inp)/zsize;
	npy_intp outp_zstride = PyArray_SIZE(outp)/zsize;

	ITYPE* dz_da = (ITYPE*) dz->data;
	ITYPE* bounds_da = (ITYPE*) bounds->data;
	DTYPE* inp_da = (DTYPE*) inp->data;
	DTYPE* outp_da = (DTYPE*) outp->data;
	DTYPE* inp_loc;
	DTYPE* outp_loc;

	NpyIter* local_iter;
	NpyIter_IterNextFunc* iternext;

	npy_intp loopsize;
	ITYPE* loop_col;
	ITYPE* loop_row;
	DTYPE* loop_coeff;
	npy_intp loop_col_stride;
	npy_intp loop_row_stride;
	npy_intp loop_coeff_stride;

	npy_intp ib, ie, iz, idz, oz;
	int i;

	#pragma omp parallel num_threads(threads) private(local_iter, iternext)
	{

		#pragma omp critical
		local_iter = NpyIter_Copy(iter);

		iternext = NpyIter_GetIterNext(local_iter, NULL);

		#pragma omp for collapse(2) private(iz, idz, oz, inp_loc, outp_loc, ib, ie, loopsize, loop_col, loop_row, loop_coeff, loop_col_stride, loop_row_stride, loop_coeff_stride, i)
		for(iz=0; iz<zsize; iz++)
		{
			for(idz=0; idz<dz_size; idz++)
			{
				oz = iz + dz_da[idz];
				if(oz>=0 && oz<zsize)
				{
					inp_loc = inp_da + iz*inp_zstride;
					outp_loc = outp_da + oz*outp_zstride;
					ib = bounds_da[idz];
					ie = bounds_da[idz+1];

					if(ie>ib)
					{
						NpyIter_ResetToIterIndexRange(local_iter, ib, ie, NULL);

						do{
							loopsize = NpyIter_GetInnerLoopSizePtr(local_iter)[0];

							loop_col = (ITYPE*) NpyIter_GetDataPtrArray(local_iter)[0];
							loop_row = (ITYPE*) NpyIter_GetDataPtrArray(local_iter)[1];
							loop_coeff = (DTYPE*) NpyIter_GetDataPtrArray(local_iter)[2];

							loop_col_stride = NpyIter_GetInnerStrideArray(local_iter)[0]/sizeof(ITYPE);
							loop_row_stride = NpyIter_GetInnerStrideArray(local_iter)[1]/sizeof(ITYPE);
							loop_coeff_stride = NpyIter_GetInnerStrideArray(local_iter)[2]/sizeof(DTYPE);

							#pragma omp simd
							for(i=0; i<loopsize; i++)
							{
								atomic_add(outp_loc + loop_row[0], (DTYPE) 1);//loop_coeff[0] * inp_loc[loop_col[0]]);

								loop_col += loop_col_stride;
								loop_row += loop_row_stride;
								loop_coeff += loop_coeff_stride;
							}

						} while (iternext(local_iter));
					}
				}
			}
		}

		NpyIter_Deallocate(local_iter);

	}

	NpyIter_Deallocate(iter);
}

#define DTYPES(I) DTYPES ## I
#define DTYPES0 npy_float32
#define DTYPES1 npy_float64
#define DTYPES2 std::complex<npy_float32>
#define DTYPES3 std::complex<npy_float64>

#define DTYPENAMES(I) DTYPENAMES ## I
#define DTYPENAMES0 NPY_FLOAT32
#define DTYPENAMES1 NPY_FLOAT64
#define DTYPENAMES2 NPY_COMPLEX64
#define DTYPENAMES3 NPY_COMPLEX128

#define DTYPES_CNT 4

#define ITYPES(I) ITYPES ## I
#define ITYPES0 npy_int16
#define ITYPES1 npy_int32
#define ITYPES2 npy_int64
#define ITYPES3 npy_uint16
#define ITYPES4 npy_uint32
#define ITYPES5 npy_uint64

#define ITYPENAMES(I) ITYPENAMES ## I
#define ITYPENAMES0 NPY_INT16
#define ITYPENAMES1 NPY_INT32
#define ITYPENAMES2 NPY_INT64
#define ITYPENAMES3 NPY_UINT16
#define ITYPENAMES4 NPY_UINT32
#define ITYPENAMES5 NPY_UINT64

#define ITYPES_CNT 6

#define DISPATCH_INNER_CASE(z, itype, dtype)							\
	case ITYPENAMES(itype): return sparse_matvec_template<DTYPES(dtype), ITYPES(itype)>;

#define DISPATCH_CASE(z, dtype, itype_num)								\
	case DTYPENAMES(dtype): switch(itype_num) { BOOST_PP_REPEAT(ITYPES_CNT, DISPATCH_INNER_CASE, dtype) };

void (*dispatch_sparse_matvec(int dtype_num, int itype_num))(PyArrayObject*, PyArrayObject*, npy_intp, PyArrayObject*, PyArrayObject*, PyArrayObject*, PyArrayObject*, PyArrayObject*, int)
{
	switch(dtype_num){ BOOST_PP_REPEAT(DTYPES_CNT, DISPATCH_CASE, itype_num) };
}

#undef DISPATCH_INNER_CASE
#undef DISPATCH_CASE

void sparse_matvec(PyArrayObject* inp, PyArrayObject* outp, npy_intp zsize, PyArrayObject* dz, PyArrayObject* bounds, PyArrayObject* col, PyArrayObject* row, PyArrayObject* coeff, int threads)
{
	dispatch_sparse_matvec(inp->descr->type_num, col->descr->type_num)(inp, outp, zsize, dz, bounds, col, row, coeff, threads);
}
<commit_msg>removed debugging change<commit_after>#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION

#include <numpy/arrayobject.h>

#include <omp.h>
#include <stdio.h>

#include <complex>

#include <boost/preprocessor/repetition/repeat.hpp>

#include "atomic_add.hpp"

template <typename DTYPE, typename ITYPE>
void sparse_matvec_template(PyArrayObject* inp, PyArrayObject* outp, npy_intp zsize, PyArrayObject* dz, PyArrayObject* bounds, PyArrayObject* col, PyArrayObject* row, PyArrayObject* coeff, int threads)
{

	PyArrayObject* ops[3] = {col, row, coeff};
	npy_uint32 flags = NPY_ITER_EXTERNAL_LOOP|NPY_ITER_GROWINNER|NPY_ITER_RANGED|NPY_ITER_BUFFERED|NPY_ITER_DELAY_BUFALLOC;
	npy_uint32 op_flags[3] = {NPY_ITER_READONLY, NPY_ITER_READONLY, NPY_ITER_READONLY};
	NpyIter* iter = NpyIter_MultiNew(3, ops , flags, NPY_KEEPORDER, NPY_NO_CASTING, op_flags, NULL);

	npy_intp dz_size = PyArray_SIZE(dz);
	npy_intp inp_zstride = PyArray_SIZE(inp)/zsize;
	npy_intp outp_zstride = PyArray_SIZE(outp)/zsize;

	ITYPE* dz_da = (ITYPE*) dz->data;
	ITYPE* bounds_da = (ITYPE*) bounds->data;
	DTYPE* inp_da = (DTYPE*) inp->data;
	DTYPE* outp_da = (DTYPE*) outp->data;
	DTYPE* inp_loc;
	DTYPE* outp_loc;

	NpyIter* local_iter;
	NpyIter_IterNextFunc* iternext;

	npy_intp loopsize;
	ITYPE* loop_col;
	ITYPE* loop_row;
	DTYPE* loop_coeff;
	npy_intp loop_col_stride;
	npy_intp loop_row_stride;
	npy_intp loop_coeff_stride;

	npy_intp ib, ie, iz, idz, oz;
	int i;

	#pragma omp parallel num_threads(threads) private(local_iter, iternext)
	{

		#pragma omp critical
		local_iter = NpyIter_Copy(iter);

		iternext = NpyIter_GetIterNext(local_iter, NULL);

		#pragma omp for collapse(2) private(iz, idz, oz, inp_loc, outp_loc, ib, ie, loopsize, loop_col, loop_row, loop_coeff, loop_col_stride, loop_row_stride, loop_coeff_stride, i)
		for(iz=0; iz<zsize; iz++)
		{
			for(idz=0; idz<dz_size; idz++)
			{
				oz = iz + dz_da[idz];
				if(oz>=0 && oz<zsize)
				{
					inp_loc = inp_da + iz*inp_zstride;
					outp_loc = outp_da + oz*outp_zstride;
					ib = bounds_da[idz];
					ie = bounds_da[idz+1];

					if(ie>ib)
					{
						NpyIter_ResetToIterIndexRange(local_iter, ib, ie, NULL);

						do{
							loopsize = NpyIter_GetInnerLoopSizePtr(local_iter)[0];

							loop_col = (ITYPE*) NpyIter_GetDataPtrArray(local_iter)[0];
							loop_row = (ITYPE*) NpyIter_GetDataPtrArray(local_iter)[1];
							loop_coeff = (DTYPE*) NpyIter_GetDataPtrArray(local_iter)[2];

							loop_col_stride = NpyIter_GetInnerStrideArray(local_iter)[0]/sizeof(ITYPE);
							loop_row_stride = NpyIter_GetInnerStrideArray(local_iter)[1]/sizeof(ITYPE);
							loop_coeff_stride = NpyIter_GetInnerStrideArray(local_iter)[2]/sizeof(DTYPE);

							#pragma omp simd
							for(i=0; i<loopsize; i++)
							{
								atomic_add(outp_loc + loop_row[0], loop_coeff[0] * inp_loc[loop_col[0]]);

								loop_col += loop_col_stride;
								loop_row += loop_row_stride;
								loop_coeff += loop_coeff_stride;
							}

						} while (iternext(local_iter));
					}
				}
			}
		}

		NpyIter_Deallocate(local_iter);

	}

	NpyIter_Deallocate(iter);
}

#define DTYPES(I) DTYPES ## I
#define DTYPES0 npy_float32
#define DTYPES1 npy_float64
#define DTYPES2 std::complex<npy_float32>
#define DTYPES3 std::complex<npy_float64>

#define DTYPENAMES(I) DTYPENAMES ## I
#define DTYPENAMES0 NPY_FLOAT32
#define DTYPENAMES1 NPY_FLOAT64
#define DTYPENAMES2 NPY_COMPLEX64
#define DTYPENAMES3 NPY_COMPLEX128

#define DTYPES_CNT 4

#define ITYPES(I) ITYPES ## I
#define ITYPES0 npy_int16
#define ITYPES1 npy_int32
#define ITYPES2 npy_int64
#define ITYPES3 npy_uint16
#define ITYPES4 npy_uint32
#define ITYPES5 npy_uint64

#define ITYPENAMES(I) ITYPENAMES ## I
#define ITYPENAMES0 NPY_INT16
#define ITYPENAMES1 NPY_INT32
#define ITYPENAMES2 NPY_INT64
#define ITYPENAMES3 NPY_UINT16
#define ITYPENAMES4 NPY_UINT32
#define ITYPENAMES5 NPY_UINT64

#define ITYPES_CNT 6

#define DISPATCH_INNER_CASE(z, itype, dtype)							\
	case ITYPENAMES(itype): return sparse_matvec_template<DTYPES(dtype), ITYPES(itype)>;

#define DISPATCH_CASE(z, dtype, itype_num)								\
	case DTYPENAMES(dtype): switch(itype_num) { BOOST_PP_REPEAT(ITYPES_CNT, DISPATCH_INNER_CASE, dtype) };

void (*dispatch_sparse_matvec(int dtype_num, int itype_num))(PyArrayObject*, PyArrayObject*, npy_intp, PyArrayObject*, PyArrayObject*, PyArrayObject*, PyArrayObject*, PyArrayObject*, int)
{
	switch(dtype_num){ BOOST_PP_REPEAT(DTYPES_CNT, DISPATCH_CASE, itype_num) };
}

#undef DISPATCH_INNER_CASE
#undef DISPATCH_CASE

void sparse_matvec(PyArrayObject* inp, PyArrayObject* outp, npy_intp zsize, PyArrayObject* dz, PyArrayObject* bounds, PyArrayObject* col, PyArrayObject* row, PyArrayObject* coeff, int threads)
{
	dispatch_sparse_matvec(inp->descr->type_num, col->descr->type_num)(inp, outp, zsize, dz, bounds, col, row, coeff, threads);
}
<|endoftext|>


<commit_before>#define BOOST_TEST_MODULE VectorView
#include <valarray>
#include <boost/test/unit_test.hpp>
#include "context_setup.hpp"

BOOST_AUTO_TEST_CASE(vector_view_1d)
{
    const size_t N = 1024;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    std::vector<double> x = random_vector<double>(2 * N);
    vex::vector<double> X(queue, x);
    vex::vector<double> Y(queue, N);

    cl_ulong size   = N;
    cl_long  stride = 2;

    vex::gslice<1> slice(0, &size, &stride);

    Y = slice(X);

    check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK(v == x[idx * 2]); });
}

BOOST_AUTO_TEST_CASE(vector_view_2)
{
    const size_t N = 32;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    std::valarray<double> x(N * N);
    std::iota(&x[0], &x[N * N], 0);

    // Select every even point from sub-block [(2,4) - (10,10)]:
    size_t start    = 2 * N + 4;
    size_t size[]   = {5, 4};
    size_t stride[] = {2 * N, 2};

    std::gslice std_slice(start, std::valarray<size_t>(size, 2), std::valarray<size_t>(stride, 2));

    std::valarray<double> y = x[std_slice];

    vex::vector<double> X(queue, N * N, &x[0]);
    vex::vector<double> Y(queue, size[0] * size[1]);

    vex::gslice<2> vex_slice(start, size, stride);

    Y = vex_slice(X);

    check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, y[idx]); });
}

BOOST_AUTO_TEST_CASE(vector_slicer_2d)
{
    const size_t N = 32;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    std::valarray<double> x(N * N);
    std::iota(&x[0], &x[N * N], 0);

    // Select every even point from sub-block [(2,4) - (10,10)]:
    size_t start    = 2 * N + 4;
    size_t size[]   = {5, 4};
    size_t stride[] = {2 * N, 2};

    std::gslice std_slice(start, std::valarray<size_t>(size, 2), std::valarray<size_t>(stride, 2));
    std::valarray<double> y = x[std_slice];

    vex::vector<double> X(queue, N * N, &x[0]);
    vex::vector<double> Y(queue, size[0] * size[1]);
    vex::vector<double> Z(queue, N);

    size_t dim[2] = {N, N};

    vex::slicer<2> slicer(dim);

    auto slice = slicer[vex::range(2, 2, 11)][vex::range(4, 2, 11)];

    Y = slice(X);

    check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, y[idx]); });

    Z = slicer[5](X); // Put fith row of X into Z;

    check_sample(Z, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, x[5 * N + idx]); });

    Z = slicer[vex::range()][5](X); // Puth fith column of X into Z;

    check_sample(Z, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, x[5 + N * idx]); });
}

BOOST_AUTO_TEST_CASE(vector_permutation)
{
    const size_t N = 1024;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    std::vector<double> x = random_vector<double>(N);
    vex::vector<double> X(queue, x);
    vex::vector<double> Y(queue, N);
    vex::vector<size_t> I(queue, N);

    I = N - 1 - vex::element_index();

    vex::permutation reverse(I);

    Y = reverse(X);

    check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, x[N - 1 - idx]); });
}

BOOST_AUTO_TEST_CASE(reduce_slice)
{
    const size_t N = 1024;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    vex::vector<int> X(queue, N);
    vex::Reductor<int, vex::SUM> sum(queue);
    vex::slicer<1> slice(&N);

    X = 1;

    BOOST_CHECK_EQUAL(N / 2, sum( slice[vex::range(0, 2, N)](X) ));
}

BOOST_AUTO_TEST_CASE(assign_to_view) {
    const size_t m = 32;
    const size_t n = m * m;

    std::array<size_t, 2> dim = {{m, m}};

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    vex::vector<int> x(queue, n);
    vex::slicer<1> slicer1(&n);
    vex::slicer<2> slicer2(dim);

    x = 1;

    slicer1[vex::range(1, 2, n)](x) = 2;

    check_sample(x, [&](size_t idx, int v) {
            BOOST_CHECK_EQUAL(v, idx % 2 + 1);
            });

    for(size_t i = 0; i < m; ++i)
        slicer2[vex::range()][i](x) = i;

    check_sample(x, [&](size_t idx, int v) {
            BOOST_CHECK_EQUAL(v, idx % m);
            });

    vex::vector<size_t> I(ctx, m);

    I = vex::element_index() * m;

    vex::permutation first_col(I);

    first_col(x) = 42;

    for(size_t i = 0; i < m; ++i)
        BOOST_CHECK_EQUAL(x[i * m], 42);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Fixed bug in tests/vector_view.cpp<commit_after>#define BOOST_TEST_MODULE VectorView
#include <valarray>
#include <boost/test/unit_test.hpp>
#include "context_setup.hpp"

BOOST_AUTO_TEST_CASE(vector_view_1d)
{
    const size_t N = 1024;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    std::vector<double> x = random_vector<double>(2 * N);
    vex::vector<double> X(queue, x);
    vex::vector<double> Y(queue, N);

    cl_ulong size   = N;
    cl_long  stride = 2;

    vex::gslice<1> slice(0, &size, &stride);

    Y = slice(X);

    check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK(v == x[idx * 2]); });
}

BOOST_AUTO_TEST_CASE(vector_view_2)
{
    const size_t N = 32;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    std::valarray<double> x(N * N);
    std::iota(&x[0], &x[N * N], 0);

    // Select every even point from sub-block [(2,4) - (10,10)]:
    size_t start    = 2 * N + 4;
    size_t size[]   = {5, 4};
    size_t stride[] = {2 * N, 2};

    std::gslice std_slice(start, std::valarray<size_t>(size, 2), std::valarray<size_t>(stride, 2));

    std::valarray<double> y = x[std_slice];

    vex::vector<double> X(queue, N * N, &x[0]);
    vex::vector<double> Y(queue, size[0] * size[1]);

    vex::gslice<2> vex_slice(start, size, stride);

    Y = vex_slice(X);

    check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, y[idx]); });
}

BOOST_AUTO_TEST_CASE(vector_slicer_2d)
{
    const size_t N = 32;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    std::valarray<double> x(N * N);
    std::iota(&x[0], &x[N * N], 0);

    // Select every even point from sub-block [(2,4) - (10,10)]:
    size_t start    = 2 * N + 4;
    size_t size[]   = {5, 4};
    size_t stride[] = {2 * N, 2};

    std::gslice std_slice(start, std::valarray<size_t>(size, 2), std::valarray<size_t>(stride, 2));
    std::valarray<double> y = x[std_slice];

    vex::vector<double> X(queue, N * N, &x[0]);
    vex::vector<double> Y(queue, size[0] * size[1]);
    vex::vector<double> Z(queue, N);

    size_t dim[2] = {N, N};

    vex::slicer<2> slicer(dim);

    auto slice = slicer[vex::range(2, 2, 11)][vex::range(4, 2, 11)];

    Y = slice(X);

    check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, y[idx]); });

    Z = slicer[5](X); // Put fith row of X into Z;

    check_sample(Z, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, x[5 * N + idx]); });

    Z = slicer[vex::range()][5](X); // Puth fith column of X into Z;

    check_sample(Z, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, x[5 + N * idx]); });
}

BOOST_AUTO_TEST_CASE(vector_permutation)
{
    const size_t N = 1024;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    std::vector<double> x = random_vector<double>(N);
    vex::vector<double> X(queue, x);
    vex::vector<double> Y(queue, N);
    vex::vector<size_t> I(queue, N);

    I = N - 1 - vex::element_index();

    vex::permutation reverse(I);

    Y = reverse(X);

    check_sample(Y, [&](size_t idx, double v) { BOOST_CHECK_EQUAL(v, x[N - 1 - idx]); });
}

BOOST_AUTO_TEST_CASE(reduce_slice)
{
    const size_t N = 1024;

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    vex::vector<int> X(queue, N);
    vex::Reductor<int, vex::SUM> sum(queue);
    vex::slicer<1> slice(&N);

    X = 1;

    BOOST_CHECK_EQUAL(N / 2, sum( slice[vex::range(0, 2, N)](X) ));
}

BOOST_AUTO_TEST_CASE(assign_to_view) {
    const size_t m = 32;
    const size_t n = m * m;

    std::array<size_t, 2> dim = {{m, m}};

    std::vector<cl::CommandQueue> queue(1, ctx.queue(0));

    vex::vector<int> x(queue, n);
    vex::slicer<1> slicer1(&n);
    vex::slicer<2> slicer2(dim);

    x = 1;

    slicer1[vex::range(1, 2, n)](x) = 2;

    check_sample(x, [&](size_t idx, int v) {
            BOOST_CHECK_EQUAL(v, idx % 2 + 1);
            });

    for(size_t i = 0; i < m; ++i)
        slicer2[vex::range()][i](x) = i;

    check_sample(x, [&](size_t idx, int v) {
            BOOST_CHECK_EQUAL(v, idx % m);
            });

    vex::vector<size_t> I(queue, m);

    I = vex::element_index() * m;

    vex::permutation first_col(I);

    first_col(x) = 42;

    for(size_t i = 0; i < m; ++i)
        BOOST_CHECK_EQUAL(x[i * m], 42);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "GameProcess.h"
#include "Object.h"
#include "Engine.h"
#include "World.h"
#include "App.h"
using namespace MathLib;

CGameProcess::CGameProcess(void)
{

}

CGameProcess::~CGameProcess(void)
{

}
int CGameProcess::Init()
{
	g_Engine.pFileSystem->CacheFilesFormExt("char");
	g_Engine.pFileSystem->CacheFilesFormExt("node");
	g_Engine.pFileSystem->CacheFilesFormExt("smesh");
	g_Engine.pFileSystem->CacheFilesFormExt("sanim");

	g_Engine.pWorld->LoadWorld("data/scene/terrain/test/test.world");
	//g_Engine.pWorld->LoadWorld("data/scene/terrain/cj/cj.world");
}<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "GameProcess.h"
#include "Object.h"
#include "Engine.h"
#include "World.h"
#include "App.h"
#include "ToolsCamera.h"

using namespace MathLib;

CGameProcess::CGameProcess(void)
{

}

CGameProcess::~CGameProcess(void)
{

}
int CGameProcess::Init()
{
	g_Engine.pFileSystem->CacheFilesFormExt("char");
	g_Engine.pFileSystem->CacheFilesFormExt("node");
	g_Engine.pFileSystem->CacheFilesFormExt("smesh");
	g_Engine.pFileSystem->CacheFilesFormExt("sanim");

	g_Engine.pWorld->LoadWorld("data/scene/terrain/test/test.world");
	//g_Engine.pWorld->LoadWorld("data/scene/terrain/cj/cj.world");
	g_Engine.pControls->SetKeyPressFunc(KeyPress);
}<|endoftext|>


<commit_before>#include <iostream>
#include <gtest/gtest.h>
#include "../pipeline.h"
#include "../channel.h"
#include "../scheduler.h"
#include "../shell.h"
#include <thread>
#include <asyncply/run.h>

class ChannelTest : testing::Test { };

using cmd = cu::pipeline<int>;

cmd::link generator()
{
	return [](cmd::in&, cmd::out& yield)
	{
		for (auto& s : {100, 200, 300})
		{
			std::cout << "I am generator and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link1()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link1 and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link2()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link2 and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link3()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link3 and push " << s << std::endl;
			yield(s);
		}
	};
}

TEST(ChannelTest, pipeline)
{
	cmd(generator(), link1(), link2(), link3());
}

TEST(ChannelTest, goroutines_consumer)
{
	cu::scheduler sch;
	cu::channel<std::string> go(sch);
	// go.connect(cu::quote("__^-^__"));
	// go.connect(cu::quote("__\o/__"));
	sch.spawn([&](auto& yield) {
		// send
		for(int i=1; i<=200; ++i)
		{
			std::cout << "sending: " << i << std::endl;
			go(yield, std::to_string(i));
		}
		go.close(yield);
	});
	sch.spawn([&](auto& yield) {
		// recv
		for(;;)
		{
			auto data = go.get(yield);
			if(!data)
			{
				std::cout << "channel closed" << std::endl;
				break;
			}
			else
			{
				std::cout << "recving: " << *data << std::endl;
			}
		}
	});
	sch.run_until_complete();
}

TEST(CoroTest, TestScheduler)
{
	cu::scheduler sch;
	cu::semaphore person1(sch);
	cu::semaphore person2(sch);
	cu::semaphore other(sch);
	// person2
	sch.spawn("person2", [&](auto& yield) {
		std::cout << "Hola person1" << std::endl;
		person2.notify(yield);
		//
		person1.wait(yield);
		std::cout << "que tal ?" << std::endl;
		person2.notify(yield);
		//
		person1.wait(yield);
		std::cout << "me alegro" << std::endl;
		person2.notify(yield);
		//
		other.notify(yield);
	});
	// person1
	sch.spawn("person1", [&](auto& yield) {
		//
		person2.wait(yield);
		std::cout << "Hola person2" << std::endl;
		person1.notify(yield);
		//
		person2.wait(yield);
		std::cout << "bien!" << std::endl;
		person1.notify(yield);
		//
		person2.wait(yield);
		std::cout << "y yo ^^" << std::endl;
		//
		other.notify(yield);
	});
	// other
	sch.spawn("other", [&](auto& yield) {
		//
		other.wait(yield);
		other.wait(yield);
		std::cout << "parar!!! tengo algo importante" << std::endl;
	});
	sch.run_until_complete();
}
<commit_msg>Update test_channel.cpp<commit_after>#include <iostream>
#include <gtest/gtest.h>
#include "../pipeline.h"
#include "../channel.h"
#include "../scheduler.h"
#include "../shell.h"
#include <thread>
#include <asyncply/run.h>

class ChannelTest : testing::Test { };

using cmd = cu::pipeline<int>;

cmd::link generator()
{
	return [](cmd::in&, cmd::out& yield)
	{
		for (auto& s : {100, 200, 300})
		{
			std::cout << "I am generator and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link1()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link1 and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link2()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link2 and push " << s << std::endl;
			yield(s);
		}
	};
}

cmd::link link3()
{
	return [](cmd::in& source, cmd::out& yield)
	{
		for (auto& s : source)
		{
			std::cout << "I am link3 and push " << s << std::endl;
			yield(s);
		}
	};
}

TEST(ChannelTest, pipeline)
{
	cmd(generator(), link1(), link2(), link3());
}

TEST(ChannelTest, goroutines_consumer)
{
	cu::scheduler sch;
	cu::channel<std::string> go(sch, 5);
	// go.connect(cu::quote("__^-^__"));
	// go.connect(cu::quote("__\o/__"));
	sch.spawn([&](auto& yield) {
		// send
		for(int i=1; i<=50; ++i)
		{
			std::cout << "sending: " << i << std::endl;
			go(yield, std::to_string(i));
		}
		go.close(yield);
	});
	sch.spawn([&](auto& yield) {
		// recv
		for(;;)
		{
			auto data = go.get(yield);
			if(!data)
			{
				std::cout << "channel closed" << std::endl;
				break;
			}
			else
			{
				std::cout << "recving: " << *data << std::endl;
			}
		}
	});
	sch.run_until_complete();
}

TEST(CoroTest, TestScheduler)
{
	cu::scheduler sch;
	cu::semaphore person1(sch);
	cu::semaphore person2(sch);
	cu::semaphore other(sch);
	// person2
	sch.spawn([&](auto& yield) {
		std::cout << "Hola person1" << std::endl;
		person2.notify(yield);
		//
		person1.wait(yield);
		std::cout << "que tal ?" << std::endl;
		person2.notify(yield);
		//
		person1.wait(yield);
		std::cout << "me alegro" << std::endl;
		person2.notify(yield);
		//
		other.notify(yield);
	});
	// person1
	sch.spawn([&](auto& yield) {
		//
		person2.wait(yield);
		std::cout << "Hola person2" << std::endl;
		person1.notify(yield);
		//
		person2.wait(yield);
		std::cout << "bien!" << std::endl;
		person1.notify(yield);
		//
		person2.wait(yield);
		std::cout << "y yo ^^" << std::endl;
		//
		other.notify(yield);
	});
	// other
	sch.spawn([&](auto& yield) {
		//
		other.wait(yield);
		other.wait(yield);
		std::cout << "parar!!! tengo algo importante" << std::endl;
	});
	sch.run_until_complete();
}
<|endoftext|>


<commit_before>#include "GameProcess.h"
#include "Object.h"
#include "Engine.h"
#include "World.h"
#include "App.h"
#include "ToolsCamera.h"
#include "ControlsApp.h"
#include "MathLib.h"
#include "Game.h"
#include "Editor.h"
#include "Input.h"
#include "BlueRayUtils.h"
#include "World.h"
#include "Action.h"
#include "FPSRoleLocal.h"

using namespace MathLib;

CGameProcess::CGameProcess(void)
{

}

CGameProcess::~CGameProcess(void)
{

}
int CGameProcess::Init()
{
	g_Engine.pFileSystem->CacheFilesFormExt("char");
	g_Engine.pFileSystem->CacheFilesFormExt("node");
	g_Engine.pFileSystem->CacheFilesFormExt("smesh");
	g_Engine.pFileSystem->CacheFilesFormExt("sanim");

	g_Engine.pWorld->LoadWorld("data/scene/terrain/test/test.world");
	//g_Engine.pWorld->LoadWorld("data/scene/terrain/cj/cj.world");
	g_Engine.pControls->SetKeyPressFunc(KeyPress);
	g_Engine.pControls->SetKeyReleaseFunc(KeyRelease);

	m_pRole = new CFPSRoleLocal();
	m_pRole->Init(10001, "data/role/hero/FpsRole/fps.char");

	m_pRole->SetActorPosition(vec3(0, 0, 0));	//设置角色初始位置。以门处作为原点，三维坐标系vec3是向量
	m_pSkillSystem = new CSkillSystem(this);
	m_pCameraBase = new CCameraBase();
	m_pCameraBase->SetEnabled(1);
	g_pSysControl->SetMouseGrab(1);

	m_pStarControl = new CStarControl();
	m_pRayControl = new CRayControl();

	return 1;
}

int CGameProcess::ShutDown()			//关闭游戏进程
{
	delete m_pRole;
	delete m_pSkillSystem;
	delete m_pCameraBase;
	delete m_pStarControl;
	delete m_pRayControl;

	DelAllListen();
	return 0;
}

int CGameProcess::Update()
{
	float ifps = g_Engine.pGame->GetIFps();

	if (g_Engine.pInput->IsKeyDown('1'))
	{
		CAction* pAction = m_pRole->OrceAction("attack02");
		if (pAction)
		{
			pAction->SetupSkillThrow(vec3_zero, -1.0f, 2.0f);
			m_pRole->StopMove();
		}
	}
	else if (g_Engine.pInput->IsKeyDown('2'))
	{
		CAction* pAction = m_pRole->OrceAction("skill01");
		if (pAction)
		{
			m_pRole->StopMove();
		}
	}
	else if (g_Engine.pInput->IsKeyDown('3'))
	{
		CAction* pAction = m_pRole->OrceAction("skill02");
		if (pAction)
		{
			m_pRole->StopMove();
			CRoleBase* pTarget = NULL;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 15.0f)
				{
					pTarget = m_vAIList[i];
					break;
				}
			}
			if (pTarget)
			{
				CVector<int> vTarget;
				vTarget.Append(pTarget->GetRoleID());
				pAction->SetupSkillBulletTarget(vTarget);
				m_pRole->SetDirection((pTarget->GetPosition() - m_pRole->GetPosition()).normalize(), 1);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('4'))//多发子弹
	{
		CAction* pAction = m_pRole->OrceAction("skill02");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<int> vTarget;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
				{
					vTarget.Append(m_vAIList[i]->GetRoleID());
				}
			}
			if (!vTarget.Empty())
			{
				pAction->SetupSkillBulletTarget(vTarget);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('5'))
	{
		CAction* pAction = m_pRole->OrceAction("skill03");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<vec3> vPos;
			pAction->SetupSkillTargetPoint(vPos);
		}
	}
	else if (g_Engine.pInput->IsKeyDown('6'))
	{
		CAction* pAction = m_pRole->OrceAction("skill06");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<vec3> vPos;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
					vPos.Append(m_vAIList[i]->GetPosition());

			}
			pAction->SetupSkillTargetPoint(vPos);
		}
	}
	else if (g_Engine.pInput->IsKeyDown('7'))
	{
		CAction* pAction = m_pRole->OrceAction("skill05");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<int> vTarget;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
					vTarget.Append(m_vAIList[i]->GetRoleID());
			}
			if (!vTarget.Empty())
			{
				pAction->SetupSkillBulletTarget(vTarget);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('8'))
	{
		CAction* pAction = m_pRole->OrceAction("skill07");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<vec3> vPos;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
					vPos.Append(m_vAIList[i]->GetPosition());
			}
			pAction->SetupSkillBulletPosition(vPos);
		}
	}
	else if (g_Engine.pInput->IsKeyDown('9'))
	{
		CAction* pAction = m_pRole->OrceAction("skill08");
		if (pAction)
		{
			m_pRole->StopMove();
			pAction->SetupSkillBulletDirection(1);
		}

	}
	else if (g_Engine.pInput->IsKeyUp(CInput::KEY_ESC))
	{
		g_Engine.pApp->Exit();
	}
	if(g_Engine.pInput->IsLBDown())
	{
		vec3 p0,p1;
		BlueRay::GetPlayerMouseDirection(p0,p1);
		vec3 vRetPoint,vRetNormal;
		int nS = -1;
		g_Engine.pWorld->GetIntersection(p0,p1,CBRObject::MASK_SCENE,vRetPoint,vRetNormal,nS);

		if(-1 != nS)
		{
			m_pRole->MoveToPath(vRetPoint);
		}
	}
	return 0;
}

<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "GameProcess.h"
#include "Object.h"
#include "Engine.h"
#include "World.h"
#include "App.h"
#include "ToolsCamera.h"
#include "ControlsApp.h"
#include "MathLib.h"
#include "Game.h"
#include "Editor.h"
#include "Input.h"
#include "BlueRayUtils.h"
#include "World.h"
#include "Action.h"
#include "FPSRoleLocal.h"

using namespace MathLib;

CGameProcess::CGameProcess(void)
{

}

CGameProcess::~CGameProcess(void)
{

}
int CGameProcess::Init()
{
	g_Engine.pFileSystem->CacheFilesFormExt("char");
	g_Engine.pFileSystem->CacheFilesFormExt("node");
	g_Engine.pFileSystem->CacheFilesFormExt("smesh");
	g_Engine.pFileSystem->CacheFilesFormExt("sanim");

	g_Engine.pWorld->LoadWorld("data/scene/terrain/test/test.world");
	//g_Engine.pWorld->LoadWorld("data/scene/terrain/cj/cj.world");
	g_Engine.pControls->SetKeyPressFunc(KeyPress);
	g_Engine.pControls->SetKeyReleaseFunc(KeyRelease);

	m_pRole = new CFPSRoleLocal();
	m_pRole->Init(10001, "data/role/hero/FpsRole/fps.char");

	m_pRole->SetActorPosition(vec3(0, 0, 0));	//设置角色初始位置。以门处作为原点，三维坐标系vec3是向量
	m_pSkillSystem = new CSkillSystem(this);
	m_pCameraBase = new CCameraBase();
	m_pCameraBase->SetEnabled(1);
	g_pSysControl->SetMouseGrab(1);

	m_pStarControl = new CStarControl();
	m_pRayControl = new CRayControl();

	return 1;
}

int CGameProcess::ShutDown()			//关闭游戏进程
{
	delete m_pRole;
	delete m_pSkillSystem;
	delete m_pCameraBase;
	delete m_pStarControl;
	delete m_pRayControl;

	DelAllListen();
	return 0;
}

int CGameProcess::Update()
{
	float ifps = g_Engine.pGame->GetIFps();

	if (g_Engine.pInput->IsKeyDown('1'))
	{
		CAction* pAction = m_pRole->OrceAction("attack02");
		if (pAction)
		{
			pAction->SetupSkillThrow(vec3_zero, -1.0f, 2.0f);
			m_pRole->StopMove();
		}
	}
	else if (g_Engine.pInput->IsKeyDown('2'))
	{
		CAction* pAction = m_pRole->OrceAction("skill01");
		if (pAction)
		{
			m_pRole->StopMove();
		}
	}
	else if (g_Engine.pInput->IsKeyDown('3'))
	{
		CAction* pAction = m_pRole->OrceAction("skill02");
		if (pAction)
		{
			m_pRole->StopMove();
			CRoleBase* pTarget = NULL;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 15.0f)
				{
					pTarget = m_vAIList[i];
					break;
				}
			}
			if (pTarget)
			{
				CVector<int> vTarget;
				vTarget.Append(pTarget->GetRoleID());
				pAction->SetupSkillBulletTarget(vTarget);
				m_pRole->SetDirection((pTarget->GetPosition() - m_pRole->GetPosition()).normalize(), 1);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('4'))//多发子弹
	{
		CAction* pAction = m_pRole->OrceAction("skill02");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<int> vTarget;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
				{
					vTarget.Append(m_vAIList[i]->GetRoleID());
				}
			}
			if (!vTarget.Empty())
			{
				pAction->SetupSkillBulletTarget(vTarget);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('5'))
	{
		CAction* pAction = m_pRole->OrceAction("skill03");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<vec3> vPos;
			pAction->SetupSkillTargetPoint(vPos);
		}
	}
	else if (g_Engine.pInput->IsKeyDown('6'))
	{
		CAction* pAction = m_pRole->OrceAction("skill06");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<vec3> vPos;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
					vPos.Append(m_vAIList[i]->GetPosition());

			}
			pAction->SetupSkillTargetPoint(vPos);
		}
	}
	else if (g_Engine.pInput->IsKeyDown('7'))
	{
		CAction* pAction = m_pRole->OrceAction("skill05");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<int> vTarget;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
					vTarget.Append(m_vAIList[i]->GetRoleID());
			}
			if (!vTarget.Empty())
			{
				pAction->SetupSkillBulletTarget(vTarget);
			}
		}
	}
	else if (g_Engine.pInput->IsKeyDown('8'))
	{
		CAction* pAction = m_pRole->OrceAction("skill07");
		if (pAction)
		{
			m_pRole->StopMove();
			CVector<vec3> vPos;
			for (int i = 0; i < 20; i++)
			{
				float l = (m_vAIList[i]->GetPosition() - m_pRole->GetPosition()).length();
				if (l > 5.0f && l < 20.0f)
					vPos.Append(m_vAIList[i]->GetPosition());
			}
			pAction->SetupSkillBulletPosition(vPos);
		}
	}
	else if (g_Engine.pInput->IsKeyDown('9'))
	{
		CAction* pAction = m_pRole->OrceAction("skill08");
		if (pAction)
		{
			m_pRole->StopMove();
			pAction->SetupSkillBulletDirection(1);
		}

	}
	else if (g_Engine.pInput->IsKeyUp(CInput::KEY_ESC))
	{
		g_Engine.pApp->Exit();
	}
	if(g_Engine.pInput->IsLBDown())
	{
		vec3 p0,p1;
		BlueRay::GetPlayerMouseDirection(p0,p1);
		vec3 vRetPoint,vRetNormal;
		int nS = -1;
		g_Engine.pWorld->GetIntersection(p0,p1,CBRObject::MASK_SCENE,vRetPoint,vRetNormal,nS);

		if(-1 != nS)
		{
			m_pRole->MoveToPath(vRetPoint);
		}
	}
	for(int i = 0;i < 20;i++)
	{
		if(!m_vAIList[i]->IsMoveing())
		{
			vec3 vPos = vec3(g_Engine.pGame->GetRandomFloat(-20.0f,20.0f),g_Engine.pGame->GetRandomFloat(-20.0f,20.0f),1.1f);
			m_vAIList[i]->MoveToPath(vPos);
		}

		m_vAIList[i]->Update(ifps);
	}
	return 0;
}

<|endoftext|>


<commit_before>/* ======================================================================
File Name     : HandGesture.cpp
Creation Time : 20141015 15:14:24
=========================================================================
Copyright (c),2014-, Po-Jen Hsu.  Contact: clusterga@gmail.com
See the README file in the top-level directory for license.
========================================================================= */
#include "CmdLine.h"
#include "CvRGBCamera.h"
#include "Distribution.h"
#include "VirtualInput.h"
#include "ScreenTool.h"
#include "XMLTool.h"

int main(int argc, char **argv)
{
		module_XMLTool::XMLTool *pXMLTool = new module_XMLTool::XMLTool();
		std::string dat_path = "dat/";

		std::string VirtualInput_XML_file_name = dat_path;
		VirtualInput_XML_file_name.append("0.xml");
		std::vector<std::vector<int> > key_array(5, std::vector<int> (4) );
		if(pXMLTool->setupVirtualInputKeyMap(VirtualInput_XML_file_name.c_str(), key_array) != 0) {
				std::cerr << "Error! Cannot initial kep map" << std::endl;
				exit(-1);
		}

		std::string BinaryFilter_XML_file_name = dat_path;
		BinaryFilter_XML_file_name.append("BinaryFilter.xml");
		std::vector<std::vector<int> > boundary_array(3, std::vector<int> (2) );
		if(pXMLTool->setupBinaryFilter(BinaryFilter_XML_file_name.c_str(), boundary_array) != 0) {
				std::cerr << "Error! Cannot load BinaryFilter parameters" << std::endl;
				exit(-1);
		}

		std::string CvRGBCamera_XML_file_name = dat_path;
		CvRGBCamera_XML_file_name.append("CvRGBCamera.xml");
		std::vector<std::vector<int> > camera_array(1, std::vector<int> (6) );
		if(pXMLTool->setupCvRGBCamera(CvRGBCamera_XML_file_name.c_str(), camera_array) != 0) {
				std::cerr << "Error! Cannot load CvRGBCamera parameters" << std::endl;
				exit(-1);
		}

		std::string GestureThreshold_XML_file_name = dat_path;
		GestureThreshold_XML_file_name.append("GestureThreshold.xml");
		std::vector<std::vector<int> > threshold_array(1, std::vector<int> (10) );
		if(pXMLTool->setupGestureThreshold(GestureThreshold_XML_file_name.c_str(), threshold_array) != 0) {
				std::cerr << "Error! Cannot load BinaryFilter parameters" << std::endl;
				exit(-1);
		}

		std::string ROI_XML_file_name = dat_path;
		ROI_XML_file_name.append("BinaryFilter.xml");
		std::vector<std::vector<int> > ROI_array(1, std::vector<int> (5) );
		if(pXMLTool->setupROI(ROI_XML_file_name.c_str(), ROI_array) != 0) {
				std::cerr << "Error! Cannot load BinaryFilter parameters" << std::endl;
				exit(-1);
		}

		int camera_id = camera_array[0][0];
		int camera_x = camera_array[0][1];
		int camera_y = camera_array[0][2];
		int camera_fps = camera_array[0][3];
		int camera_brightness = camera_array[0][4];
		int camera_contrast = camera_array[0][5];

		int cut_x_lower = ROI_array[0][0]; // 35;
		int cut_x_upper = ROI_array[0][1]; // 35;
		int cut_y_lower = ROI_array[0][2]; // 50;
		int cut_y_upper = ROI_array[0][3]; // 20;
		int ROI_x_lower = cut_x_lower*(camera_x/160);
		int ROI_x_upper = camera_x - cut_x_upper*(camera_x/160);
		int ROI_y_lower = cut_y_lower*(camera_y/120);
		int ROI_y_upper = camera_y - cut_y_upper*(camera_y/120);
		int ROI_x_length = ROI_x_upper - ROI_x_lower + 1;
		int ROI_y_length = ROI_y_upper - ROI_y_lower + 1;
		int ROI_sum_threshold = ROI_array[0][4];

        int threshold_key_x_left = threshold_array[0][0];//6;
		int threshold_key_x_right = threshold_array[0][1];
        int threshold_key_y_up = threshold_array[0][2];//5;
		int threshold_key_y_down = threshold_array[0][3] ;
        int threshold_move_x = threshold_array[0][4];// 2;
        int threshold_move_y = threshold_array[0][5];// 2;
		int count_threshold_short = threshold_array[0][6];
		int count_threshold_long = threshold_array[0][7];;
		int move_factor = threshold_array[0][8];
//		int move_step = threshold_array[0][9];

		threshold_key_x_left = threshold_key_x_left * (camera_x/160);
		threshold_key_x_right = threshold_key_x_right * (camera_x/160);
		threshold_key_y_up = threshold_key_y_up * (camera_y/120);
		threshold_key_y_down = threshold_key_y_down * (camera_y/120);
		threshold_move_x = threshold_move_x * (camera_x/160);
		threshold_move_y = threshold_move_y * (camera_y/120);

//		int lower1 = 0;
//		int upper1 = 50;
//		int lower2 = 50;
//		int upper2 = 173;
//		int lower3 = 20; //20
//		int upper3 = 230;//230;

		int lower1 = boundary_array[0][0];  //H_upper H/2; 0-180
		int upper1 = boundary_array[0][1];  //H_upper
		int lower2 = boundary_array[1][0];    //S_lower   S*255;  0-255
		int upper2 = boundary_array[1][1];  //S_upper
		int lower3 = boundary_array[2][0];    //V_lower   V*255;  0-255
		int upper3 = boundary_array[2][1];  //V_upper

		module_CmdLine::CmdLine *pCmdLine = new module_CmdLine::CmdLine();
		pCmdLine->setup(argc, argv);

		module_CvRGBCamera::CvRGBCamera *pCvRGBCamera = new module_CvRGBCamera::CvRGBCamera(camera_id);

		module_Distribution::Distribution *pDistribution = new module_Distribution::Distribution(camera_x, camera_y);

		pDistribution->imageROI(ROI_x_lower, ROI_x_upper, ROI_y_lower, ROI_y_upper);

		module_VirtualInput::VirtualInput *pVirtualInput = new module_VirtualInput::VirtualInput();

		module_ScreenTool::ScreenTool *pScreenTool = new module_ScreenTool::ScreenTool();
		pScreenTool->X11Screen();
		int screen_x = pScreenTool->screenWidth();
		int screen_y = pScreenTool->screenHeight();
		int move_type = 1;
		pVirtualInput->setup(screen_x, screen_y, move_type);
		sleep(1);

		if (pCvRGBCamera->setup(camera_x, camera_y, camera_fps, camera_brightness, camera_contrast) == 1) {
			std::cerr << "Error!" << std::endl;
		}

		pCvRGBCamera->setupAutosizeWindow("frame");

//		pCvRGBCamera->setupOpenGLWindow("hist_x");
//		pCvRGBCamera->setupOpenGLWindow("pos_x");

//		pCvRGBCamera->setupOpenGLWindow("hist_y");
//		pCvRGBCamera->setupOpenGLWindow("pos_y");

		int pos_x, pos_y, pos_pre_x = 0, pos_pre_y = 0, diff_x = 0, diff_y = 0;
		cv::Mat dist_x = cv::Mat::zeros(1, camera_x, CV_32SC1);
		cv::Mat dist_y = cv::Mat::zeros(camera_y, 1, CV_32SC1);

		int left_count = 0, right_count = 0, up_count = 0, down_count = 0;

		int no_move = -1;
		int press = 1, release = 0;

		int dx, dy;

		int read_key = -1;

//		char return_key[32];

//		Display *display;

		while (read_key != 27) {
				read_key = cv::waitKey(15);

//				XQueryKeymap(display, return_key);
//				std::cout << "return_key = " << return_key << std::endl;
				pDistribution->imageDist2d(pCvRGBCamera->HSVBinary(lower1, lower2, lower3, upper1, upper2, upper3), (int *)dist_x.data, (int *)dist_y.data);
				pos_x = pDistribution->imageDistMean((int *)dist_x.data, 0, ROI_x_length, ROI_sum_threshold);
				pos_y = pDistribution->imageDistMean((int *)dist_y.data, 0, ROI_y_length, ROI_sum_threshold);
				pCvRGBCamera->showBinary("frame", ROI_x_lower, ROI_x_upper, ROI_y_lower, ROI_y_upper);
//				pCvRGBCamera->showHistogram("hist_x", (int *)dist_x.data, 0, ROI_x_length);
//				pCvRGBCamera->showHistogram("hist_y", (int *)dist_y.data, 0, ROI_y_length);
//				pCvRGBCamera->showLine("pos_x",pos_x, ROI_x_lower, ROI_x_upper);
//				pCvRGBCamera->showLine("pos_y",pos_y, ROI_y_lower, ROI_y_upper);
//				std::cerr << "pos_x=" << pos_x << ",diff_x=" << diff_x << ",pos_y=" << pos_y << ",diff_y=" << diff_y << std::endl;
				if (read_key > 47 && read_key < 58) {  //"0" == 48, "1" == 49, ... , "9" == 57
						VirtualInput_XML_file_name = dat_path;
						VirtualInput_XML_file_name.append(std::to_string(read_key-48)).append(".xml");
						if(pXMLTool->setupVirtualInputKeyMap(VirtualInput_XML_file_name.c_str(), key_array) == 0) {
								pVirtualInput->setup(screen_x, screen_y, key_array[0][1]);
								std::cout << "Loading " << VirtualInput_XML_file_name << std::endl;
						} else {
								std::cerr << "Error! Cannot find " << VirtualInput_XML_file_name << std::endl;
						}
						read_key = -1;
				}

				if (left_count > 0) {
						left_count--;
				}
				if (right_count > 0) {
						right_count--;
				}
				if (up_count > 0) {
						up_count--;
				}
				if (down_count > 0) {
						down_count--;
				}

				if (pos_x > -1 && pos_y > -1) {
						if (key_array[0][0] > 0) {
								dx = diff_x * move_factor;
								dy = diff_y * move_factor;
						} else {
								dx = no_move;
								dy = no_move;
						}

						if (diff_x < -threshold_key_x_left && left_count == 0) {

								std::cout << "Detect Left!!" << std::endl;
								pVirtualInput->control(press, key_array[1][0], key_array[2][0], key_array[3][0], key_array[4][0], dx, no_move);
								if (key_array[0][0] == 0) {
										usleep(100);
										pVirtualInput->control(release, key_array[1][0], key_array[2][0], key_array[3][0], key_array[4][0], no_move, no_move);
										up_count = count_threshold_long;
										down_count = count_threshold_long;
								}
								left_count = count_threshold_short;
								right_count = count_threshold_long;

						}

						if (diff_x > threshold_key_x_right && right_count == 0) {

								std::cout << "Detect Right!!" << std::endl;
								pVirtualInput->control(press, key_array[1][1], key_array[2][1], key_array[3][1], key_array[4][1], dx, no_move);
								if (key_array[0][0] == 0) {
										usleep(100);
										pVirtualInput->control(release, key_array[1][1], key_array[2][1], key_array[3][1], key_array[4][1], no_move, no_move);
										up_count = count_threshold_long;
										down_count = count_threshold_long;
								}
								left_count = count_threshold_long;
								right_count = count_threshold_short;
						}

						if (diff_y < -threshold_key_y_up && up_count == 0) {

								std::cout << "Detect Up!!" << std::endl;
								pVirtualInput->control(press, key_array[1][2], key_array[2][2], key_array[3][2], key_array[4][2], no_move, dy);
								if (key_array[0][0] == 0) {
										usleep(100);
										pVirtualInput->control(release, key_array[1][2], key_array[2][2], key_array[3][2], key_array[4][2], no_move, no_move);
										right_count = count_threshold_long;
										left_count = count_threshold_long;
								}
								up_count = count_threshold_short;
								down_count = count_threshold_long;
						}

						if (diff_y > threshold_key_y_down && down_count == 0) {

								std::cout << "Detect Down!!" << std::endl;
								pVirtualInput->control(press, key_array[1][3], key_array[2][3], key_array[3][3], key_array[4][3], no_move, dy);
								if (key_array[0][0] == 0) {
										usleep(100);
										pVirtualInput->control(release, key_array[1][3], key_array[2][3], key_array[3][3], key_array[4][3], no_move, no_move);
										right_count = count_threshold_long;
										left_count = count_threshold_long;
								}
								up_count = count_threshold_long;
								down_count = count_threshold_short;
						}

						diff_x = pos_pre_x - pos_x;
						diff_y = pos_y - pos_pre_y;
						pos_pre_x = pos_x;
						pos_pre_y = pos_y;
//						printf("%d %d %d %d %d %d %d %d\n", 0, -1, -1, -1, -1, 0, 0, 1);
				}
		}

		delete pXMLTool;

		delete pScreenTool;

		delete pVirtualInput;

		delete pDistribution;

		delete pCvRGBCamera;

		delete pCmdLine;

		exit(0);
}

<commit_msg>HandGesture.cpp<commit_after><|endoftext|>


<commit_before>#include "aerial_autonomy/controllers/constant_heading_depth_controller.h"
#include "aerial_autonomy/common/math.h"
#include "aerial_autonomy/log/log.h"
#include <glog/logging.h>

bool ConstantHeadingDepthController::runImplementation(
    PositionYaw sensor_data, Position goal, VelocityYawRate &control) {
  tf::Vector3 current_tracking_vector(sensor_data.x, sensor_data.y,
                                      sensor_data.z);
  tf::Vector3 desired_tracking_vector(goal.x, goal.y, goal.z);
  tf::Vector3 desired_tracking_direction =
      desired_tracking_vector / desired_tracking_vector.length();
  tf::Vector3 tracking_error =
      (current_tracking_vector - desired_tracking_vector);
  tf::Vector3 tracking_error_radial =
      desired_tracking_direction *
      (tracking_error.dot(desired_tracking_direction));
  tf::Vector3 tracking_error_tangential =
      tracking_error - tracking_error_radial;
  tf::Vector3 desired_vel_tf =
      tracking_error_radial * config_.radial_gain() +
      tracking_error_tangential * config_.tangential_gain();

  if (desired_vel_tf.length() > config_.max_velocity()) {
    desired_vel_tf *= config_.max_velocity() / desired_vel_tf.length();
  } else if (desired_vel_tf.length() < config_.min_velocity()) {
    desired_vel_tf *= config_.min_velocity() / desired_vel_tf.length();
  }

  double error_yaw =
      math::angleWrap(std::atan2(desired_tracking_direction.getY(),
                                 desired_tracking_direction.getX()) -
                      sensor_data.yaw);
  double yaw_rate =
      math::clamp(config_.yaw_gain() * error_yaw, -config_.max_yaw_rate(),
                  config_.max_yaw_rate());
  control = VelocityYawRate(desired_vel_tf.getX(), desired_vel_tf.getY(),
                            desired_vel_tf.getZ(), yaw_rate);
  return true;
}

ControllerStatus ConstantHeadingDepthController::isConvergedImplementation(
    PositionYaw sensor_data, Position goal) {
  double error_yaw =
      math::angleWrap(std::atan2(goal.y, goal.x) - sensor_data.yaw);
  Position error = Position(sensor_data.x, sensor_data.y, sensor_data.z) - goal;
  ControllerStatus status(ControllerStatus::Active);
  status << " Error Position, Yaw: " << error.x << error.y << error.z
         << error_yaw;
  DATA_LOG("constant_heading_depth_controller")
      << error.x << error.y << error.z << error_yaw << DataStream::endl;
  const PositionControllerConfig &position_controller_config =
      config_.position_controller_config();
  const config::Position &tolerance_pos =
      position_controller_config.goal_position_tolerance();
  const double &tolerance_yaw = position_controller_config.goal_yaw_tolerance();
  // Compare
  if (std::abs(error.x) < tolerance_pos.x() &&
      std::abs(error.y) < tolerance_pos.y() &&
      std::abs(error.z) < tolerance_pos.z() &&
      std::abs(error_yaw) < tolerance_yaw) {
    VLOG_EVERY_N(1, 50) << "Reached goal";
    status.setStatus(ControllerStatus::Completed, "Reached Goal");
  }
  return status;
}
<commit_msg>Add tracking vector to ConstantHeadingDepthController data log<commit_after>#include "aerial_autonomy/controllers/constant_heading_depth_controller.h"
#include "aerial_autonomy/common/math.h"
#include "aerial_autonomy/log/log.h"
#include <glog/logging.h>

bool ConstantHeadingDepthController::runImplementation(
    PositionYaw sensor_data, Position goal, VelocityYawRate &control) {
  tf::Vector3 current_tracking_vector(sensor_data.x, sensor_data.y,
                                      sensor_data.z);
  tf::Vector3 desired_tracking_vector(goal.x, goal.y, goal.z);
  tf::Vector3 desired_tracking_direction =
      desired_tracking_vector / desired_tracking_vector.length();
  tf::Vector3 tracking_error =
      (current_tracking_vector - desired_tracking_vector);
  tf::Vector3 tracking_error_radial =
      desired_tracking_direction *
      (tracking_error.dot(desired_tracking_direction));
  tf::Vector3 tracking_error_tangential =
      tracking_error - tracking_error_radial;
  tf::Vector3 desired_vel_tf =
      tracking_error_radial * config_.radial_gain() +
      tracking_error_tangential * config_.tangential_gain();

  if (desired_vel_tf.length() > config_.max_velocity()) {
    desired_vel_tf *= config_.max_velocity() / desired_vel_tf.length();
  } else if (desired_vel_tf.length() < config_.min_velocity()) {
    desired_vel_tf *= config_.min_velocity() / desired_vel_tf.length();
  }

  double error_yaw =
      math::angleWrap(std::atan2(desired_tracking_direction.getY(),
                                 desired_tracking_direction.getX()) -
                      sensor_data.yaw);
  double yaw_rate =
      math::clamp(config_.yaw_gain() * error_yaw, -config_.max_yaw_rate(),
                  config_.max_yaw_rate());
  control = VelocityYawRate(desired_vel_tf.getX(), desired_vel_tf.getY(),
                            desired_vel_tf.getZ(), yaw_rate);
  return true;
}

ControllerStatus ConstantHeadingDepthController::isConvergedImplementation(
    PositionYaw sensor_data, Position goal) {
  double error_yaw =
      math::angleWrap(std::atan2(goal.y, goal.x) - sensor_data.yaw);
  Position error = Position(sensor_data.x, sensor_data.y, sensor_data.z) - goal;
  ControllerStatus status(ControllerStatus::Active);
  status << " Error Position, Yaw: " << error.x << error.y << error.z
         << error_yaw;
  DATA_LOG("constant_heading_depth_controller")
      << error.x << error.y << error.z << error_yaw << sensor_data.x
      << sensor_data.y << sensor_data.z << sensor_data.yaw << DataStream::endl;
  const PositionControllerConfig &position_controller_config =
      config_.position_controller_config();
  const config::Position &tolerance_pos =
      position_controller_config.goal_position_tolerance();
  const double &tolerance_yaw = position_controller_config.goal_yaw_tolerance();
  // Compare
  if (std::abs(error.x) < tolerance_pos.x() &&
      std::abs(error.y) < tolerance_pos.y() &&
      std::abs(error.z) < tolerance_pos.z() &&
      std::abs(error_yaw) < tolerance_yaw) {
    VLOG_EVERY_N(1, 50) << "Reached goal";
    status.setStatus(ControllerStatus::Completed, "Reached Goal");
  }
  return status;
}
<|endoftext|>


<commit_before>#pragma once

#include "event_queue.hpp"

namespace krbn {
namespace manipulator {
namespace detail {
class base {
public:
  virtual ~base(void) {
  }

  virtual manipulate(event_queue& event_queue) = 0;
};
} // namespace detail
} // namespace manipulator
} // namespace krbn
<commit_msg>detail -> details<commit_after>#pragma once

#include "manipulator/event_queue.hpp"

namespace krbn {
namespace manipulator {
namespace details {
class base {
public:
  virtual ~base(void) {
  }

  virtual void manipulate(event_queue& event_queue) = 0;
};
} // namespace details
} // namespace manipulator
} // namespace krbn
<|endoftext|>


<commit_before>//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

//
// Code that is used by both the Unix corerun and coreconsole.
//

#include <assert.h>
#include <dirent.h>
#include <dlfcn.h>
#include <limits.h>
#include <set>
#include <string>
#include <string.h>
#include <sys/stat.h>

// The name of the CoreCLR native runtime DLL
#if defined(__APPLE__)
static const char * const coreClrDll = "libcoreclr.dylib";
#else
static const char * const coreClrDll = "libcoreclr.so";
#endif

// Windows types used by the ExecuteAssembly function
typedef unsigned int DWORD;
typedef const char16_t* LPCWSTR;
typedef const char* LPCSTR;
typedef int32_t HRESULT;

#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)

// Prototype of the ExecuteAssembly function from the libcoreclr.do
typedef HRESULT (*ExecuteAssemblyFunction)(
                    LPCSTR exePath,
                    LPCSTR coreClrPath,
                    LPCSTR appDomainFriendlyName,
                    int propertyCount,
                    LPCSTR* propertyKeys,
                    LPCSTR* propertyValues,
                    int argc,
                    LPCSTR* argv,
                    LPCSTR managedAssemblyPath,
                    LPCSTR entryPointAssemblyName,
                    LPCSTR entryPointTypeName,
                    LPCSTR entryPointMethodsName,
                    DWORD* exitCode);

bool GetAbsolutePath(const char* path, std::string& absolutePath)
{
    bool result = false;

    char realPath[PATH_MAX];
    if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
    {
        absolutePath.assign(realPath);
        // realpath should return canonicalized path without the trailing slash
        assert(absolutePath.back() != '/');

        result = true;
    }

    return result;
}

bool GetDirectory(const char* absolutePath, std::string& directory)
{
    directory.assign(absolutePath);
    size_t lastSlash = directory.rfind('/');
    if (lastSlash != std::string::npos)
    {
        directory.erase(lastSlash);
        return true;
    }

    return false;
}

bool GetClrFilesAbsolutePath(const char* currentExePath, const char* clrFilesPath, std::string& clrFilesAbsolutePath)
{
    std::string clrFilesRelativePath;
    const char* clrFilesPathLocal = clrFilesPath;
    if (clrFilesPathLocal == nullptr)
    {
        // There was no CLR files path specified, use the folder of the corerun/coreconsole
        if (!GetDirectory(currentExePath, clrFilesRelativePath))
        {
            perror("Failed to get directory from argv[0]");
            return false;
        }

        clrFilesPathLocal = clrFilesRelativePath.c_str();

        // TODO: consider using an env variable (if defined) as a fall-back.
        // The windows version of the corerun uses core_root env variable
    }

    if (!GetAbsolutePath(clrFilesPathLocal, clrFilesAbsolutePath))
    {
        perror("Failed to convert CLR files path to absolute path");
        return false;
    }

    return true;
}

void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList)
{
    const char * const tpaExtensions[] = {
                ".ni.dll",      // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
                ".dll",
                ".ni.exe",
                ".exe",
                };

    DIR* dir = opendir(directory);
    if (dir == nullptr)
    {
        return;
    }

    std::set<std::string> addedAssemblies;

    // Walk the directory for each extension separately so that we first get files with .ni.dll extension,
    // then files with .dll extension, etc.
    for (int extIndex = 0; extIndex < sizeof(tpaExtensions) / sizeof(tpaExtensions[0]); extIndex++)
    {
        const char* ext = tpaExtensions[extIndex];
        int extLength = strlen(ext);

        struct dirent* entry;

        // For all entries in the directory
        while ((entry = readdir(dir)) != nullptr)
        {
            // We are interested in files only
            switch (entry->d_type)
            {
            case DT_REG:
                break;

            // Handle symlinks and file systems that do not support d_type
            case DT_LNK:
            case DT_UNKNOWN:
                {
                    std::string fullFilename;

                    fullFilename.append(directory);
                    fullFilename.append("/");
                    fullFilename.append(entry->d_name);

                    struct stat sb;
                    if (stat(fullFilename.c_str(), &sb) == -1)
                    {
                        continue;
                    }

                    if (!S_ISREG(sb.st_mode))
                    {
                        continue;
                    }
                }
                break;

            default:
                continue;
            }

            std::string filename(entry->d_name);

            // Check if the extension matches the one we are looking for
            int extPos = filename.length() - extLength;
            if ((extPos <= 0) || (filename.compare(extPos, extLength, ext) != 0))
            {
                continue;
            }

            std::string filenameWithoutExt(filename.substr(0, extPos));

            // Make sure if we have an assembly with multiple extensions present,
            // we insert only one version of it.
            if (addedAssemblies.find(filenameWithoutExt) == addedAssemblies.end())
            {
                addedAssemblies.insert(filenameWithoutExt);

                tpaList.append(directory);
                tpaList.append("/");
                tpaList.append(filename);
                tpaList.append(":");
            }
        }

        // Rewind the directory stream to be able to iterate over it for the next extension
        rewinddir(dir);
    }

    closedir(dir);
}

int ExecuteManagedAssembly(
            const char* currentExeAbsolutePath,
            const char* clrFilesAbsolutePath,
            const char* managedAssemblyAbsolutePath,
            int managedAssemblyArgc,
            const char** managedAssemblyArgv)
{
    // Indicates failure
    int exitCode = -1;

    std::string coreClrDllPath(clrFilesAbsolutePath);
    coreClrDllPath.append("/");
    coreClrDllPath.append(coreClrDll);

    if (coreClrDllPath.length() >= PATH_MAX)
    {
        fprintf(stderr, "Absolute path to libcoreclr.so too long\n");
        return -1;
    }

    // Get just the path component of the managed assembly path
    std::string appPath;
    GetDirectory(managedAssemblyAbsolutePath, appPath);

    std::string nativeDllSearchDirs(appPath);
    nativeDllSearchDirs.append(":");
    nativeDllSearchDirs.append(clrFilesAbsolutePath);

    std::string tpaList;
    AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList);

    void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL);
    if (coreclrLib != nullptr)
    {
        ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "ExecuteAssembly");
        if (executeAssembly != nullptr)
        {
            // Allowed property names:
            // APPBASE
            // - The base path of the application from which the exe and other assemblies will be loaded
            //
            // TRUSTED_PLATFORM_ASSEMBLIES
            // - The list of complete paths to each of the fully trusted assemblies
            //
            // APP_PATHS
            // - The list of paths which will be probed by the assembly loader
            //
            // APP_NI_PATHS
            // - The list of additional paths that the assembly loader will probe for ngen images
            //
            // NATIVE_DLL_SEARCH_DIRECTORIES
            // - The list of paths that will be probed for native DLLs called by PInvoke
            //
            const char *propertyKeys[] = {
                "TRUSTED_PLATFORM_ASSEMBLIES",
                "APP_PATHS",
                "APP_NI_PATHS",
                "NATIVE_DLL_SEARCH_DIRECTORIES",
                "AppDomainCompatSwitch"
            };
            const char *propertyValues[] = {
                // TRUSTED_PLATFORM_ASSEMBLIES
                tpaList.c_str(),
                // APP_PATHS
                appPath.c_str(),
                // APP_NI_PATHS
                appPath.c_str(),
                // NATIVE_DLL_SEARCH_DIRECTORIES
                nativeDllSearchDirs.c_str(),
                // AppDomainCompatSwitch
                "UseLatestBehaviorWhenTFMNotSpecified"
            };

            HRESULT st = executeAssembly(
                            currentExeAbsolutePath,
                            coreClrDllPath.c_str(),
                            "unixcorerun",
                            sizeof(propertyKeys) / sizeof(propertyKeys[0]),
                            propertyKeys,
                            propertyValues,
                            managedAssemblyArgc,
                            managedAssemblyArgv,
                            managedAssemblyAbsolutePath,
                            NULL,
                            NULL,
                            NULL,
                            (DWORD*)&exitCode);

            if (!SUCCEEDED(st))
            {
                fprintf(stderr, "ExecuteAssembly failed - status: 0x%08x\n", st);
            }
        }
        else
        {
            fprintf(stderr, "Function ExecuteAssembly not found in the libcoreclr.so\n");
        }

        if (dlclose(coreclrLib) != 0)
        {
            fprintf(stderr, "Warning - dlclose failed\n");
        }
    }
    else
    {
        char* error = dlerror();
        fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error);
    }

    return exitCode;
}
<commit_msg>Fix unixcoreruncommon build error on FreeBSD Needed cstdlib to build properly<commit_after>//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

//
// Code that is used by both the Unix corerun and coreconsole.
//

#include <cstdlib>
#include <assert.h>
#include <dirent.h>
#include <dlfcn.h>
#include <limits.h>
#include <set>
#include <string>
#include <string.h>
#include <sys/stat.h>

// The name of the CoreCLR native runtime DLL
#if defined(__APPLE__)
static const char * const coreClrDll = "libcoreclr.dylib";
#else
static const char * const coreClrDll = "libcoreclr.so";
#endif

// Windows types used by the ExecuteAssembly function
typedef unsigned int DWORD;
typedef const char16_t* LPCWSTR;
typedef const char* LPCSTR;
typedef int32_t HRESULT;

#define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)

// Prototype of the ExecuteAssembly function from the libcoreclr.do
typedef HRESULT (*ExecuteAssemblyFunction)(
                    LPCSTR exePath,
                    LPCSTR coreClrPath,
                    LPCSTR appDomainFriendlyName,
                    int propertyCount,
                    LPCSTR* propertyKeys,
                    LPCSTR* propertyValues,
                    int argc,
                    LPCSTR* argv,
                    LPCSTR managedAssemblyPath,
                    LPCSTR entryPointAssemblyName,
                    LPCSTR entryPointTypeName,
                    LPCSTR entryPointMethodsName,
                    DWORD* exitCode);

bool GetAbsolutePath(const char* path, std::string& absolutePath)
{
    bool result = false;

    char realPath[PATH_MAX];
    if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
    {
        absolutePath.assign(realPath);
        // realpath should return canonicalized path without the trailing slash
        assert(absolutePath.back() != '/');

        result = true;
    }

    return result;
}

bool GetDirectory(const char* absolutePath, std::string& directory)
{
    directory.assign(absolutePath);
    size_t lastSlash = directory.rfind('/');
    if (lastSlash != std::string::npos)
    {
        directory.erase(lastSlash);
        return true;
    }

    return false;
}

bool GetClrFilesAbsolutePath(const char* currentExePath, const char* clrFilesPath, std::string& clrFilesAbsolutePath)
{
    std::string clrFilesRelativePath;
    const char* clrFilesPathLocal = clrFilesPath;
    if (clrFilesPathLocal == nullptr)
    {
        // There was no CLR files path specified, use the folder of the corerun/coreconsole
        if (!GetDirectory(currentExePath, clrFilesRelativePath))
        {
            perror("Failed to get directory from argv[0]");
            return false;
        }

        clrFilesPathLocal = clrFilesRelativePath.c_str();

        // TODO: consider using an env variable (if defined) as a fall-back.
        // The windows version of the corerun uses core_root env variable
    }

    if (!GetAbsolutePath(clrFilesPathLocal, clrFilesAbsolutePath))
    {
        perror("Failed to convert CLR files path to absolute path");
        return false;
    }

    return true;
}

void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList)
{
    const char * const tpaExtensions[] = {
                ".ni.dll",      // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
                ".dll",
                ".ni.exe",
                ".exe",
                };

    DIR* dir = opendir(directory);
    if (dir == nullptr)
    {
        return;
    }

    std::set<std::string> addedAssemblies;

    // Walk the directory for each extension separately so that we first get files with .ni.dll extension,
    // then files with .dll extension, etc.
    for (int extIndex = 0; extIndex < sizeof(tpaExtensions) / sizeof(tpaExtensions[0]); extIndex++)
    {
        const char* ext = tpaExtensions[extIndex];
        int extLength = strlen(ext);

        struct dirent* entry;

        // For all entries in the directory
        while ((entry = readdir(dir)) != nullptr)
        {
            // We are interested in files only
            switch (entry->d_type)
            {
            case DT_REG:
                break;

            // Handle symlinks and file systems that do not support d_type
            case DT_LNK:
            case DT_UNKNOWN:
                {
                    std::string fullFilename;

                    fullFilename.append(directory);
                    fullFilename.append("/");
                    fullFilename.append(entry->d_name);

                    struct stat sb;
                    if (stat(fullFilename.c_str(), &sb) == -1)
                    {
                        continue;
                    }

                    if (!S_ISREG(sb.st_mode))
                    {
                        continue;
                    }
                }
                break;

            default:
                continue;
            }

            std::string filename(entry->d_name);

            // Check if the extension matches the one we are looking for
            int extPos = filename.length() - extLength;
            if ((extPos <= 0) || (filename.compare(extPos, extLength, ext) != 0))
            {
                continue;
            }

            std::string filenameWithoutExt(filename.substr(0, extPos));

            // Make sure if we have an assembly with multiple extensions present,
            // we insert only one version of it.
            if (addedAssemblies.find(filenameWithoutExt) == addedAssemblies.end())
            {
                addedAssemblies.insert(filenameWithoutExt);

                tpaList.append(directory);
                tpaList.append("/");
                tpaList.append(filename);
                tpaList.append(":");
            }
        }

        // Rewind the directory stream to be able to iterate over it for the next extension
        rewinddir(dir);
    }

    closedir(dir);
}

int ExecuteManagedAssembly(
            const char* currentExeAbsolutePath,
            const char* clrFilesAbsolutePath,
            const char* managedAssemblyAbsolutePath,
            int managedAssemblyArgc,
            const char** managedAssemblyArgv)
{
    // Indicates failure
    int exitCode = -1;

    std::string coreClrDllPath(clrFilesAbsolutePath);
    coreClrDllPath.append("/");
    coreClrDllPath.append(coreClrDll);

    if (coreClrDllPath.length() >= PATH_MAX)
    {
        fprintf(stderr, "Absolute path to libcoreclr.so too long\n");
        return -1;
    }

    // Get just the path component of the managed assembly path
    std::string appPath;
    GetDirectory(managedAssemblyAbsolutePath, appPath);

    std::string nativeDllSearchDirs(appPath);
    nativeDllSearchDirs.append(":");
    nativeDllSearchDirs.append(clrFilesAbsolutePath);

    std::string tpaList;
    AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList);

    void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL);
    if (coreclrLib != nullptr)
    {
        ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "ExecuteAssembly");
        if (executeAssembly != nullptr)
        {
            // Allowed property names:
            // APPBASE
            // - The base path of the application from which the exe and other assemblies will be loaded
            //
            // TRUSTED_PLATFORM_ASSEMBLIES
            // - The list of complete paths to each of the fully trusted assemblies
            //
            // APP_PATHS
            // - The list of paths which will be probed by the assembly loader
            //
            // APP_NI_PATHS
            // - The list of additional paths that the assembly loader will probe for ngen images
            //
            // NATIVE_DLL_SEARCH_DIRECTORIES
            // - The list of paths that will be probed for native DLLs called by PInvoke
            //
            const char *propertyKeys[] = {
                "TRUSTED_PLATFORM_ASSEMBLIES",
                "APP_PATHS",
                "APP_NI_PATHS",
                "NATIVE_DLL_SEARCH_DIRECTORIES",
                "AppDomainCompatSwitch"
            };
            const char *propertyValues[] = {
                // TRUSTED_PLATFORM_ASSEMBLIES
                tpaList.c_str(),
                // APP_PATHS
                appPath.c_str(),
                // APP_NI_PATHS
                appPath.c_str(),
                // NATIVE_DLL_SEARCH_DIRECTORIES
                nativeDllSearchDirs.c_str(),
                // AppDomainCompatSwitch
                "UseLatestBehaviorWhenTFMNotSpecified"
            };

            HRESULT st = executeAssembly(
                            currentExeAbsolutePath,
                            coreClrDllPath.c_str(),
                            "unixcorerun",
                            sizeof(propertyKeys) / sizeof(propertyKeys[0]),
                            propertyKeys,
                            propertyValues,
                            managedAssemblyArgc,
                            managedAssemblyArgv,
                            managedAssemblyAbsolutePath,
                            NULL,
                            NULL,
                            NULL,
                            (DWORD*)&exitCode);

            if (!SUCCEEDED(st))
            {
                fprintf(stderr, "ExecuteAssembly failed - status: 0x%08x\n", st);
            }
        }
        else
        {
            fprintf(stderr, "Function ExecuteAssembly not found in the libcoreclr.so\n");
        }

        if (dlclose(coreclrLib) != 0)
        {
            fprintf(stderr, "Warning - dlclose failed\n");
        }
    }
    else
    {
        char* error = dlerror();
        fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error);
    }

    return exitCode;
}
<|endoftext|>


<commit_before>/*
 * opencog/atoms/base/Link.cc
 *
 * Copyright (C) 2008-2010 OpenCog Foundation
 * Copyright (C) 2002-2007 Novamente LLC
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdio.h>

#include <opencog/util/exceptions.h>
#include <opencog/util/Logger.h>

#include <opencog/atoms/base/ClassServer.h>
#include <opencog/atoms/base/Node.h>
#include <opencog/atomspace/AtomTable.h>

#include <boost/range/algorithm.hpp>

#include "Link.h"

//#define DPRINTF printf
#define DPRINTF(...)

using namespace opencog;

void Link::resort(void)
{
    // Caution: this comparison function MUST BE EXACTLY THE SAME as
    // the one in AtomTable.cc, used for Unordered links. Changing
    // this without changing the other one will break things!
    std::sort(_outgoing.begin(), _outgoing.end(), handle_less());
}

void Link::init(const HandleSeq& outgoingVector)
{
    if (not classserver().isA(_type, LINK)) {
        throw InvalidParamException(TRACE_INFO,
            "Link ctor: Atom type is not a Link: '%d' %s.",
            _type, classserver().getTypeName(_type).c_str());
    }

    _outgoing = outgoingVector;
    // If the link is unordered, it will be normalized by sorting the
    // elements in the outgoing list.
    if (classserver().isA(_type, UNORDERED_LINK)) {
        resort();
    }
}

Link::~Link()
{
    DPRINTF("Deleting link:\n%s\n", this->toString().c_str());
}

std::string Link::toShortString(const std::string& indent) const
{
    std::stringstream answer;
    std::string more_indent = indent + "  ";

    answer << indent << "(" << classserver().getTypeName(_type);
    if (not getTruthValue()->isDefaultTV())
        answer << " " << getTruthValue()->toString();
    answer << "\n";

    // Here the target string is made. If a target is a node, its name is
    // concatenated. If it's a link, all its properties are concatenated.
    for (const Handle& h : _outgoing) {
        if (h.operator->() != NULL)
            answer << h->toShortString(more_indent);
        else
            answer << more_indent << "Undefined Atom!\n";
    }

    answer << indent << ") ; [" << _uuid << "]";

    if (_atomTable)
        answer << "[" << _atomTable->get_uuid() << "]\n";
    else
        answer << "[NULL]\n";

    return answer.str();
}

std::string Link::toString(const std::string& indent) const
{
    std::string answer = indent;
    std::string more_indent = indent + "  ";

    answer += "(" + classserver().getTypeName(_type);

    // Print the TV and AV only if its not the default.
    if (not getAttentionValue()->isDefaultAV())
        answer += " (av " +
             std::to_string(getAttentionValue()->getSTI()) + " " +
             std::to_string(getAttentionValue()->getLTI()) + " " +
             std::to_string(getAttentionValue()->getVLTI()) + ")";

    if (not getTruthValue()->isDefaultTV())
        answer += " " + getTruthValue()->toString();

    answer += "\n";
    // Here, the outset string is made. If a target is a node,
    // its name is concatenated. If it's a link, then recurse.
    for (const Handle& h : _outgoing) {
        if (h.operator->() != NULL)
            answer += h->toString(more_indent);
        else
            answer += more_indent + "Undefined Atom!\n";
    }

    answer += indent + ") ; [" +
            std::to_string(_uuid) + "][" +
            std::to_string(_atomTable? _atomTable->get_uuid() : -1) +
            "]\n";

    return answer;
}

// Content-based comparison.
bool Link::operator==(const Atom& other) const
{
    // If other points to this, then have equality.
    if (this == &other) return true;

    // Rule out obvious mis-matches, based on the hash.
    if (get_hash() != other.get_hash()) return false;
    if (getType() != other.getType()) return false;

    Arity sz = getArity();
    if (sz != other.getArity()) return false;

    // Perform a content-compare on the outgoing set.
    const HandleSeq& rhs = other.getOutgoingSet();
    for (Arity i = 0; i < sz; i++)
    {
        if (*((AtomPtr)_outgoing[i]) != *((AtomPtr)rhs[i]))
            return false;
    }
    return true;
}

// Content-based ordering.
bool Link::operator<(const Atom& other) const
{
    if (get_hash() < other.get_hash()) return true;
    if (other.get_hash() < get_hash()) return false;

    // We get to here only if the hashes are equal.
    // Compare the contents directly, for this
    // (hopefully rare) case.
    if (getType() == other.getType()) {
        const HandleSeq& outgoing = getOutgoingSet();
        const HandleSeq& other_outgoing = other.getOutgoingSet();
        Arity arity = outgoing.size();
        Arity other_arity = other_outgoing.size();
        if (arity == other_arity) {
            Arity i = 0;
            while (i < arity) {
                Handle ll = outgoing[i];
                Handle rl = other_outgoing[i];
                if (ll == rl)
                    i++;
                else
                    return ll->operator<(*rl.atom_ptr());
            }
            return false;
        } else
            return arity < other_arity;
    } else
        return getType() < other.getType();
}

/// Returns a Merkle tree hash -- that is, the hash of this link
/// chains the hash values of the child atoms, as well.
ContentHash Link::compute_hash() const
{
	// djb hash
	ContentHash hsh = 5381;
	hsh += (hsh <<5) + getType();

	for (const Handle& h: _outgoing)
	{
		hsh += (hsh <<5) + h->get_hash(); // recursive!
	}

	// Links will always have the MSB set.
	ContentHash mask = ((ContentHash) 1UL) << (8*sizeof(ContentHash) - 1);
	hsh |= mask;

	if (Handle::INVALID_HASH == hsh) hsh -= 1;
	_content_hash = hsh;
	return _content_hash;
}
<commit_msg>Simplify the content-ordering function.<commit_after>/*
 * opencog/atoms/base/Link.cc
 *
 * Copyright (C) 2008-2010 OpenCog Foundation
 * Copyright (C) 2002-2007 Novamente LLC
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdio.h>

#include <opencog/util/exceptions.h>
#include <opencog/util/Logger.h>

#include <opencog/atoms/base/ClassServer.h>
#include <opencog/atoms/base/Node.h>
#include <opencog/atomspace/AtomTable.h>

#include <boost/range/algorithm.hpp>

#include "Link.h"

//#define DPRINTF printf
#define DPRINTF(...)

using namespace opencog;

void Link::resort(void)
{
    // Caution: this comparison function MUST BE EXACTLY THE SAME as
    // the one in AtomTable.cc, used for Unordered links. Changing
    // this without changing the other one will break things!
    std::sort(_outgoing.begin(), _outgoing.end(), handle_less());
}

void Link::init(const HandleSeq& outgoingVector)
{
    if (not classserver().isA(_type, LINK)) {
        throw InvalidParamException(TRACE_INFO,
            "Link ctor: Atom type is not a Link: '%d' %s.",
            _type, classserver().getTypeName(_type).c_str());
    }

    _outgoing = outgoingVector;
    // If the link is unordered, it will be normalized by sorting the
    // elements in the outgoing list.
    if (classserver().isA(_type, UNORDERED_LINK)) {
        resort();
    }
}

Link::~Link()
{
    DPRINTF("Deleting link:\n%s\n", this->toString().c_str());
}

std::string Link::toShortString(const std::string& indent) const
{
    std::stringstream answer;
    std::string more_indent = indent + "  ";

    answer << indent << "(" << classserver().getTypeName(_type);
    if (not getTruthValue()->isDefaultTV())
        answer << " " << getTruthValue()->toString();
    answer << "\n";

    // Here the target string is made. If a target is a node, its name is
    // concatenated. If it's a link, all its properties are concatenated.
    for (const Handle& h : _outgoing) {
        if (h.operator->() != NULL)
            answer << h->toShortString(more_indent);
        else
            answer << more_indent << "Undefined Atom!\n";
    }

    answer << indent << ") ; [" << _uuid << "]";

    if (_atomTable)
        answer << "[" << _atomTable->get_uuid() << "]\n";
    else
        answer << "[NULL]\n";

    return answer.str();
}

std::string Link::toString(const std::string& indent) const
{
    std::string answer = indent;
    std::string more_indent = indent + "  ";

    answer += "(" + classserver().getTypeName(_type);

    // Print the TV and AV only if its not the default.
    if (not getAttentionValue()->isDefaultAV())
        answer += " (av " +
             std::to_string(getAttentionValue()->getSTI()) + " " +
             std::to_string(getAttentionValue()->getLTI()) + " " +
             std::to_string(getAttentionValue()->getVLTI()) + ")";

    if (not getTruthValue()->isDefaultTV())
        answer += " " + getTruthValue()->toString();

    answer += "\n";
    // Here, the outset string is made. If a target is a node,
    // its name is concatenated. If it's a link, then recurse.
    for (const Handle& h : _outgoing) {
        if (h.operator->() != NULL)
            answer += h->toString(more_indent);
        else
            answer += more_indent + "Undefined Atom!\n";
    }

    answer += indent + ") ; [" +
            std::to_string(_uuid) + "][" +
            std::to_string(_atomTable? _atomTable->get_uuid() : -1) +
            "]\n";

    return answer;
}

// Content-based comparison.
bool Link::operator==(const Atom& other) const
{
    // If other points to this, then have equality.
    if (this == &other) return true;

    // Rule out obvious mis-matches, based on the hash.
    if (get_hash() != other.get_hash()) return false;
    if (getType() != other.getType()) return false;

    Arity sz = getArity();
    if (sz != other.getArity()) return false;

    // Perform a content-compare on the outgoing set.
    const HandleSeq& rhs = other.getOutgoingSet();
    for (Arity i = 0; i < sz; i++)
    {
        if (*((AtomPtr)_outgoing[i]) != *((AtomPtr)rhs[i]))
            return false;
    }
    return true;
}

// Content-based ordering.
bool Link::operator<(const Atom& other) const
{
    if (get_hash() < other.get_hash()) return true;
    if (other.get_hash() < get_hash()) return false;

    // We get to here only if the hashes are equal.
    // Compare the contents directly, for this
    // (hopefully rare) case.
    if (getType() != other.getType())
        return getType() < other.getType();

    const HandleSeq& outgoing = getOutgoingSet();
    const HandleSeq& other_outgoing = other.getOutgoingSet();
    Arity arity = outgoing.size();
    Arity other_arity = other_outgoing.size();
    if (arity != other_arity)
        return arity < other_arity;

    for (Arity i=0; i < arity; i++)
    {
        const Handle& ll(outgoing[i]);
        const AtomPtr& rl(other_outgoing[i]);
        if (ll->operator!=(*rl))
            return ll->operator<(*rl);
    }
    return false;
}

/// Returns a Merkle tree hash -- that is, the hash of this link
/// chains the hash values of the child atoms, as well.
ContentHash Link::compute_hash() const
{
	// djb hash
	ContentHash hsh = 5381;
	hsh += (hsh <<5) + getType();

	for (const Handle& h: _outgoing)
	{
		hsh += (hsh <<5) + h->get_hash(); // recursive!
	}

	// Links will always have the MSB set.
	ContentHash mask = ((ContentHash) 1UL) << (8*sizeof(ContentHash) - 1);
	hsh |= mask;

	if (Handle::INVALID_HASH == hsh) hsh -= 1;
	_content_hash = hsh;
	return _content_hash;
}
<|endoftext|>