<commit_before>
/*

  Tessellation only GLU library with FASTUIDRAW modifications
   - all but tessellation removed
   - arbitary winding rule
   - prefix public functions with fastuidraw_
   - prefix public macros with FASTUIDRAW_
   - change source and header files to cpp and hpp extension
   - so that API header allows for C++ niceties of overloading
   - begin call backs pass a winding number
   - remove triangle strips and fans rendering
   - remove edge flag call back
   - points provided are 2D only (skip computation of plane and projection)

  Original liscense is below

 */

/*
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice including the dates of first publication and
 * either this permission notice or a reference to
 * http://oss.sgi.com/projects/FreeB/
 * shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 * shall not be used in advertising or otherwise to promote the sale, use or
 * other dealings in this Software without prior written authorization from
 * Silicon Graphics, Inc.
 */

#pragma once

#include <climits>

/* the ID FASTUIDRAW_GLU_NULL_CLIENT_ID is reserved for use
   by FASTUIDRAW_GLU to represent a "NULL" vertex, do not
   use this ID (which is set to max unsigned int).
 */
#define FASTUIDRAW_GLU_NULL_CLIENT_ID (UINT_MAX)

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

/* Boolean */
#define FASTUIDRAW_GLU_FALSE                          0
#define FASTUIDRAW_GLU_TRUE                           1
typedef unsigned char   FASTUIDRAW_GLUboolean;
typedef unsigned int    FASTUIDRAW_GLUenum;

#define FASTUIDRAW_GLU_INVALID_ENUM                   100900
#define FASTUIDRAW_GLU_INVALID_VALUE                  100901
#define FASTUIDRAW_GLU_OUT_OF_MEMORY                  100902
#define FASTUIDRAW_GLU_INCOMPATIBLE_GL_VERSION        100903
#define FASTUIDRAW_GLU_INVALID_OPERATION              100904

/* Primitive type, avoid dependence on GL headers */
#define FASTUIDRAW_GLU_LINE_LOOP 0x0002
#define FASTUIDRAW_GLU_TRIANGLES 0x0004

/* TessCallback */
#define FASTUIDRAW_GLU_TESS_BEGIN                     100100
#define FASTUIDRAW_GLU_BEGIN                          100100
typedef void (*fastuidraw_glu_tess_function_begin)( FASTUIDRAW_GLUenum type, int winding_number);

#define FASTUIDRAW_GLU_TESS_VERTEX                    100101
#define FASTUIDRAW_GLU_VERTEX                         100101
typedef void (*fastuidraw_glu_tess_function_vertex)(unsigned int vertex_id);

#define FASTUIDRAW_GLU_TESS_END                       100102
#define FASTUIDRAW_GLU_END                            100102
typedef void (*fastuidraw_glu_tess_function_end)(void);

#define FASTUIDRAW_GLU_TESS_ERROR                     100103
typedef void (*fastuidraw_glu_tess_function_error)(FASTUIDRAW_GLUenum errnum);

#define FASTUIDRAW_GLU_TESS_COMBINE                   100105
typedef void (*fastuidraw_glu_tess_function_combine)(double x, double y, unsigned int data[4],
                                                     double weight[4], unsigned int *outData);

#define FASTUIDRAW_GLU_TESS_BEGIN_DATA                100106
typedef void (*fastuidraw_glu_tess_function_begin_data)(FASTUIDRAW_GLUenum type, int winding_number, void *polygon_data);

#define FASTUIDRAW_GLU_TESS_VERTEX_DATA               100107
typedef void (*fastuidraw_glu_tess_function_vertex_data)(unsigned int vertex_id, void *polygon_data);

#define FASTUIDRAW_GLU_TESS_END_DATA                  100108
typedef void (*fastuidraw_glu_tess_function_end_data)(void *polygon_data);

#define FASTUIDRAW_GLU_TESS_ERROR_DATA                100109
typedef void (*fastuidraw_glu_tess_function_error_data)(FASTUIDRAW_GLUenum errnum, void *polygon_data);

#define FASTUIDRAW_GLU_TESS_COMBINE_DATA              100111
typedef void (*fastuidraw_glu_tess_function_combine_data)(double x, double y, unsigned int data[4],
                                                          double weight[4], unsigned int *outData,
                                                          void *polygon_data);

  /*
    additions from FASTUIDRAW, use a call back for the winding rule
    function signature is:

    FASTUIDRAW_GLU_TESS_WINDING_CALLBACK--> FASTUIDRAW_GLUboolean fill_region(int winding_number)
    FASTUIDRAW_GLU_TESS_WINDING_CALLBACK_DATA --> FASTUIDRAW_GLUboolean fill_region(int winding_number, void *polygon_data)

    return GL_TRUE if the winding_number dictates to fill the region
    return GL_FALSE if the winding_number dictates to not fill the region
  */
#define FASTUIDRAW_GLU_TESS_WINDING_CALLBACK 200100
typedef FASTUIDRAW_GLUboolean (*fastuidraw_glu_tess_function_winding)(int winding_number);

#define FASTUIDRAW_GLU_TESS_WINDING_CALLBACK_DATA 200101
typedef FASTUIDRAW_GLUboolean (*fastuidraw_glu_tess_function_winding_data)(int winding_number, void *polygon_data);

/* TessContour */
#define FASTUIDRAW_GLU_CW                             100120
#define FASTUIDRAW_GLU_CCW                            100121
#define FASTUIDRAW_GLU_INTERIOR                       100122
#define FASTUIDRAW_GLU_EXTERIOR                       100123
#define FASTUIDRAW_GLU_UNKNOWN                        100124

/* TessProperty */
#define FASTUIDRAW_GLU_TESS_BOUNDARY_ONLY             100141
#define FASTUIDRAW_GLU_TESS_TOLERANCE                 100142

/* TessError */
#define FASTUIDRAW_GLU_TESS_ERROR1                    100151
#define FASTUIDRAW_GLU_TESS_ERROR2                    100152
#define FASTUIDRAW_GLU_TESS_ERROR3                    100153
#define FASTUIDRAW_GLU_TESS_ERROR4                    100154
#define FASTUIDRAW_GLU_TESS_ERROR5                    100155
#define FASTUIDRAW_GLU_TESS_ERROR6                    100156
#define FASTUIDRAW_GLU_TESS_ERROR7                    100157
#define FASTUIDRAW_GLU_TESS_ERROR8                    100158
#define FASTUIDRAW_GLU_TESS_MISSING_BEGIN_POLYGON     100151
#define FASTUIDRAW_GLU_TESS_MISSING_BEGIN_CONTOUR     100152
#define FASTUIDRAW_GLU_TESS_MISSING_END_POLYGON       100153
#define FASTUIDRAW_GLU_TESS_MISSING_END_CONTOUR       100154
#define FASTUIDRAW_GLU_TESS_COORD_TOO_LARGE           100155
#define FASTUIDRAW_GLU_TESS_NEED_COMBINE_CALLBACK     100156

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

class fastuidraw_GLUtesselator;

typedef fastuidraw_GLUtesselator fastuidraw_GLUtesselatorObj;
typedef fastuidraw_GLUtesselator fastuidraw_GLUtriangulatorObj;

#define FASTUIDRAW_GLU_TESS_MAX_COORD 1.0e150

/* Internal convenience typedefs */
typedef void (*FASTUIDRAW_GLUfuncptr)(void);

fastuidraw_GLUtesselator*
fastuidraw_gluNewTess_debug(const char *file, int line);

void
fastuidraw_gluDeleteTess_debug(fastuidraw_GLUtesselator* tess, const char *file, int line);

void
fastuidraw_gluDeleteTess_release(fastuidraw_GLUtesselator* tess);

fastuidraw_GLUtesselator*
fastuidraw_gluNewTess_release(void);

#ifdef FASTUIDRAW_DEBUG

#define fastuidraw_gluNewTess fastuidraw_gluNewTess_debug(__FILE__, __LINE__);
#define fastuidraw_gluDeleteTess(tess) fastuidraw_gluDeleteTess_debug(tess, __FILE__, __LINE__)

#else

#define fastuidraw_gluNewTess fastuidraw_gluNewTess_release();
#define fastuidraw_gluDeleteTess(tess) fastuidraw_gluDeleteTess_release(tess)

#endif

void fastuidraw_gluTessBeginContour (fastuidraw_GLUtesselator* tess, FASTUIDRAW_GLUboolean contour_real);
void fastuidraw_gluTessBeginPolygon (fastuidraw_GLUtesselator* tess, void* data);
void fastuidraw_gluTessEndContour (fastuidraw_GLUtesselator* tess);
void fastuidraw_gluTessEndPolygon (fastuidraw_GLUtesselator* tess);
void fastuidraw_gluTessVertex (fastuidraw_GLUtesselator* tess, double x, double y, unsigned int vertex_id);

void fastuidraw_gluTessCallback (fastuidraw_GLUtesselator* tess, FASTUIDRAW_GLUenum which, FASTUIDRAW_GLUfuncptr CallBackFunc);

/*
  set and fetch the merging tolerance
 */
double fastuidraw_gluTessPropertyTolerance(fastuidraw_GLUtesselator* tess);
void fastuidraw_gluTessPropertyTolerance(fastuidraw_GLUtesselator *tess, double value);

/*
  set and fetch weather or not to only provide line loops
  decribing the boundary, using FASTUIDRAW_GLU_FALSE and FASTUIDRAW_GLU_TRUE.
  If value is FASTUIDRAW_GLU_TRUE, then the boundary is provided
  only as a sequence of line loops. If value is FASTUIDRAW_GLU_FALSE, then
  tessellates according to the fill rule.
 */
int fastuidraw_gluGetTessPropertyBoundaryOnly(fastuidraw_GLUtesselator *tess);
void fastuidraw_gluTessPropertyBoundaryOnly(fastuidraw_GLUtesselator *tess, int value);

#define FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(which, type, label)                \
  void fastuidraw_gluTessCallback##label(fastuidraw_GLUtesselator *tess, type f)

FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_BEGIN, fastuidraw_glu_tess_function_begin, Begin);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_VERTEX, fastuidraw_glu_tess_function_vertex, Vertex);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_END, fastuidraw_glu_tess_function_end, End);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_ERROR, fastuidraw_glu_tess_function_error, Error);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_COMBINE, fastuidraw_glu_tess_function_combine, Combine);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_WINDING_CALLBACK, fastuidraw_glu_tess_function_winding, FillRule);

FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_BEGIN_DATA, fastuidraw_glu_tess_function_begin_data, Begin);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_VERTEX_DATA, fastuidraw_glu_tess_function_vertex_data, Vertex);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_END_DATA, fastuidraw_glu_tess_function_end_data, End);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_ERROR_DATA, fastuidraw_glu_tess_function_error_data, Error);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_COMBINE_DATA, fastuidraw_glu_tess_function_combine_data, Combine);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_WINDING_CALLBACK_DATA, fastuidraw_glu_tess_function_winding_data, FillRule);
<commit_msg>glu-tess: specify exactly how the pts from combine callback are generated<commit_after>
/*

  Tessellation only GLU library with FASTUIDRAW modifications
   - all but tessellation removed
   - arbitary winding rule
   - prefix public functions with fastuidraw_
   - prefix public macros with FASTUIDRAW_
   - change source and header files to cpp and hpp extension
   - so that API header allows for C++ niceties of overloading
   - begin call backs pass a winding number
   - remove triangle strips and fans rendering
   - remove edge flag call back
   - points provided are 2D only (skip computation of plane and projection)

  Original liscense is below

 */

/*
 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice including the dates of first publication and
 * either this permission notice or a reference to
 * http://oss.sgi.com/projects/FreeB/
 * shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Except as contained in this notice, the name of Silicon Graphics, Inc.
 * shall not be used in advertising or otherwise to promote the sale, use or
 * other dealings in this Software without prior written authorization from
 * Silicon Graphics, Inc.
 */

#pragma once

#include <climits>

/* the ID FASTUIDRAW_GLU_NULL_CLIENT_ID is reserved for use
   by FASTUIDRAW_GLU to represent a "NULL" vertex, do not
   use this ID (which is set to max unsigned int).
 */
#define FASTUIDRAW_GLU_NULL_CLIENT_ID (UINT_MAX)

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

/* Boolean */
#define FASTUIDRAW_GLU_FALSE                          0
#define FASTUIDRAW_GLU_TRUE                           1
typedef unsigned char   FASTUIDRAW_GLUboolean;
typedef unsigned int    FASTUIDRAW_GLUenum;

#define FASTUIDRAW_GLU_INVALID_ENUM                   100900
#define FASTUIDRAW_GLU_INVALID_VALUE                  100901
#define FASTUIDRAW_GLU_OUT_OF_MEMORY                  100902
#define FASTUIDRAW_GLU_INCOMPATIBLE_GL_VERSION        100903
#define FASTUIDRAW_GLU_INVALID_OPERATION              100904

/* Primitive type, avoid dependence on GL headers */
#define FASTUIDRAW_GLU_LINE_LOOP 0x0002
#define FASTUIDRAW_GLU_TRIANGLES 0x0004

/* TessCallback */
#define FASTUIDRAW_GLU_TESS_BEGIN                     100100
#define FASTUIDRAW_GLU_BEGIN                          100100
typedef void (*fastuidraw_glu_tess_function_begin)( FASTUIDRAW_GLUenum type, int winding_number);

#define FASTUIDRAW_GLU_TESS_VERTEX                    100101
#define FASTUIDRAW_GLU_VERTEX                         100101
typedef void (*fastuidraw_glu_tess_function_vertex)(unsigned int vertex_id);

#define FASTUIDRAW_GLU_TESS_END                       100102
#define FASTUIDRAW_GLU_END                            100102
typedef void (*fastuidraw_glu_tess_function_end)(void);

#define FASTUIDRAW_GLU_TESS_ERROR                     100103
typedef void (*fastuidraw_glu_tess_function_error)(FASTUIDRAW_GLUenum errnum);

/* Combine is guaranteed to combine 4 vertices coming
   from two edges:
     data[0] : vertex A for edge E
     data[1] : vertex B for edge E
     data[2] : vertex A for edge F
     data[3] : vertex B for edge F
 */
#define FASTUIDRAW_GLU_TESS_COMBINE                   100105
typedef void (*fastuidraw_glu_tess_function_combine)(double x, double y, unsigned int data[4],
                                                     double weight[4], unsigned int *outData);

#define FASTUIDRAW_GLU_TESS_BEGIN_DATA                100106
typedef void (*fastuidraw_glu_tess_function_begin_data)(FASTUIDRAW_GLUenum type, int winding_number, void *polygon_data);

#define FASTUIDRAW_GLU_TESS_VERTEX_DATA               100107
typedef void (*fastuidraw_glu_tess_function_vertex_data)(unsigned int vertex_id, void *polygon_data);

#define FASTUIDRAW_GLU_TESS_END_DATA                  100108
typedef void (*fastuidraw_glu_tess_function_end_data)(void *polygon_data);

#define FASTUIDRAW_GLU_TESS_ERROR_DATA                100109
typedef void (*fastuidraw_glu_tess_function_error_data)(FASTUIDRAW_GLUenum errnum, void *polygon_data);

#define FASTUIDRAW_GLU_TESS_COMBINE_DATA              100111
typedef void (*fastuidraw_glu_tess_function_combine_data)(double x, double y, unsigned int data[4],
                                                          double weight[4], unsigned int *outData,
                                                          void *polygon_data);

  /*
    additions from FASTUIDRAW, use a call back for the winding rule
    function signature is:

    FASTUIDRAW_GLU_TESS_WINDING_CALLBACK--> FASTUIDRAW_GLUboolean fill_region(int winding_number)
    FASTUIDRAW_GLU_TESS_WINDING_CALLBACK_DATA --> FASTUIDRAW_GLUboolean fill_region(int winding_number, void *polygon_data)

    return GL_TRUE if the winding_number dictates to fill the region
    return GL_FALSE if the winding_number dictates to not fill the region
  */
#define FASTUIDRAW_GLU_TESS_WINDING_CALLBACK 200100
typedef FASTUIDRAW_GLUboolean (*fastuidraw_glu_tess_function_winding)(int winding_number);

#define FASTUIDRAW_GLU_TESS_WINDING_CALLBACK_DATA 200101
typedef FASTUIDRAW_GLUboolean (*fastuidraw_glu_tess_function_winding_data)(int winding_number, void *polygon_data);

/* TessContour */
#define FASTUIDRAW_GLU_CW                             100120
#define FASTUIDRAW_GLU_CCW                            100121
#define FASTUIDRAW_GLU_INTERIOR                       100122
#define FASTUIDRAW_GLU_EXTERIOR                       100123
#define FASTUIDRAW_GLU_UNKNOWN                        100124

/* TessProperty */
#define FASTUIDRAW_GLU_TESS_BOUNDARY_ONLY             100141
#define FASTUIDRAW_GLU_TESS_TOLERANCE                 100142

/* TessError */
#define FASTUIDRAW_GLU_TESS_ERROR1                    100151
#define FASTUIDRAW_GLU_TESS_ERROR2                    100152
#define FASTUIDRAW_GLU_TESS_ERROR3                    100153
#define FASTUIDRAW_GLU_TESS_ERROR4                    100154
#define FASTUIDRAW_GLU_TESS_ERROR5                    100155
#define FASTUIDRAW_GLU_TESS_ERROR6                    100156
#define FASTUIDRAW_GLU_TESS_ERROR7                    100157
#define FASTUIDRAW_GLU_TESS_ERROR8                    100158
#define FASTUIDRAW_GLU_TESS_MISSING_BEGIN_POLYGON     100151
#define FASTUIDRAW_GLU_TESS_MISSING_BEGIN_CONTOUR     100152
#define FASTUIDRAW_GLU_TESS_MISSING_END_POLYGON       100153
#define FASTUIDRAW_GLU_TESS_MISSING_END_CONTOUR       100154
#define FASTUIDRAW_GLU_TESS_COORD_TOO_LARGE           100155
#define FASTUIDRAW_GLU_TESS_NEED_COMBINE_CALLBACK     100156

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

class fastuidraw_GLUtesselator;

typedef fastuidraw_GLUtesselator fastuidraw_GLUtesselatorObj;
typedef fastuidraw_GLUtesselator fastuidraw_GLUtriangulatorObj;

#define FASTUIDRAW_GLU_TESS_MAX_COORD 1.0e150

/* Internal convenience typedefs */
typedef void (*FASTUIDRAW_GLUfuncptr)(void);

fastuidraw_GLUtesselator*
fastuidraw_gluNewTess_debug(const char *file, int line);

void
fastuidraw_gluDeleteTess_debug(fastuidraw_GLUtesselator* tess, const char *file, int line);

void
fastuidraw_gluDeleteTess_release(fastuidraw_GLUtesselator* tess);

fastuidraw_GLUtesselator*
fastuidraw_gluNewTess_release(void);

#ifdef FASTUIDRAW_DEBUG

#define fastuidraw_gluNewTess fastuidraw_gluNewTess_debug(__FILE__, __LINE__);
#define fastuidraw_gluDeleteTess(tess) fastuidraw_gluDeleteTess_debug(tess, __FILE__, __LINE__)

#else

#define fastuidraw_gluNewTess fastuidraw_gluNewTess_release();
#define fastuidraw_gluDeleteTess(tess) fastuidraw_gluDeleteTess_release(tess)

#endif

void fastuidraw_gluTessBeginContour (fastuidraw_GLUtesselator* tess, FASTUIDRAW_GLUboolean contour_real);
void fastuidraw_gluTessBeginPolygon (fastuidraw_GLUtesselator* tess, void* data);
void fastuidraw_gluTessEndContour (fastuidraw_GLUtesselator* tess);
void fastuidraw_gluTessEndPolygon (fastuidraw_GLUtesselator* tess);
void fastuidraw_gluTessVertex (fastuidraw_GLUtesselator* tess, double x, double y, unsigned int vertex_id);

void fastuidraw_gluTessCallback (fastuidraw_GLUtesselator* tess, FASTUIDRAW_GLUenum which, FASTUIDRAW_GLUfuncptr CallBackFunc);

/*
  set and fetch the merging tolerance
 */
double fastuidraw_gluTessPropertyTolerance(fastuidraw_GLUtesselator* tess);
void fastuidraw_gluTessPropertyTolerance(fastuidraw_GLUtesselator *tess, double value);

/*
  set and fetch weather or not to only provide line loops
  decribing the boundary, using FASTUIDRAW_GLU_FALSE and FASTUIDRAW_GLU_TRUE.
  If value is FASTUIDRAW_GLU_TRUE, then the boundary is provided
  only as a sequence of line loops. If value is FASTUIDRAW_GLU_FALSE, then
  tessellates according to the fill rule.
 */
int fastuidraw_gluGetTessPropertyBoundaryOnly(fastuidraw_GLUtesselator *tess);
void fastuidraw_gluTessPropertyBoundaryOnly(fastuidraw_GLUtesselator *tess, int value);

#define FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(which, type, label)                \
  void fastuidraw_gluTessCallback##label(fastuidraw_GLUtesselator *tess, type f)

FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_BEGIN, fastuidraw_glu_tess_function_begin, Begin);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_VERTEX, fastuidraw_glu_tess_function_vertex, Vertex);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_END, fastuidraw_glu_tess_function_end, End);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_ERROR, fastuidraw_glu_tess_function_error, Error);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_COMBINE, fastuidraw_glu_tess_function_combine, Combine);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_WINDING_CALLBACK, fastuidraw_glu_tess_function_winding, FillRule);

FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_BEGIN_DATA, fastuidraw_glu_tess_function_begin_data, Begin);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_VERTEX_DATA, fastuidraw_glu_tess_function_vertex_data, Vertex);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_END_DATA, fastuidraw_glu_tess_function_end_data, End);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_ERROR_DATA, fastuidraw_glu_tess_function_error_data, Error);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_COMBINE_DATA, fastuidraw_glu_tess_function_combine_data, Combine);
FASTUIDRAW_GLU_TESS_TYPE_SAFE_CALL_BACK(FASTUIDRAW_GLU_TESS_WINDING_CALLBACK_DATA, fastuidraw_glu_tess_function_winding_data, FillRule);
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include <iostream>

#include "itkVector.h"

#include <vnl/vnl_vector_ref.h>
#include <vnl/vnl_vector_fixed_ref.h>
#include "vnl/vnl_math.h"

#include "mitkTestingMacros.h"
#include "mitkTypeBasics.h"
#include "mitkVector.h"
#include "mitkTypes.h" // for Equals

using namespace mitk;

/**
 * these private variables are used in the test functions
 *
 * The variable which should be copied into is set to its original value.
 * The value which should be copied is set to valuesToCopy.
 *
 * Then the copying takes place. The test is successful, if the variable which
 * should be copied into holds the valuesToCopy afterwards and is equal to the
 * vector which should be copied.
 */
static const ScalarType originalValues[]      =  {1.123456789987, 2.789456321456, 3.123654789987456};
static const float      originalValuesFloat[] =  {1.123456789987, 2.789456321456, 3.123654789987456};

static const ScalarType valuesToCopy[]        =  {4.654789123321, 5.987456789321, 6.321654987789546};
static const float      valuesToCopyFloat[]   =  {4.654789123321, 5.987456789321, 6.321654987789546};

static void Test_mitk2Mitk_DifferntTypeCompatibility(void)
{
  mitk::Vector<float, 3>  floatVector3D  = originalValuesFloat;
  mitk::Vector<double, 3> doubleVector3D = valuesToCopy;

  floatVector3D = doubleVector3D;

  MITK_TEST_CONDITION(floatVector3D == doubleVector3D, "mitk double vector assigned to mitk float vector")

  // test for correct values needs a little more love than in other cases
  // since Equal cannot compare arrays/vectors of different type
  bool correctValuesAssigned = true;
  for (int var = 0; var < 3; ++var) {
      correctValuesAssigned = correctValuesAssigned
          && Equal(floatVector3D[var], valuesToCopy[var], vnl_math::float_eps * 10.0);
  }
  MITK_TEST_CONDITION(correctValuesAssigned, "correct values were assigned within float accuracy")
}

static void Test_itk2Mitk_Compatibility(void)
{
  Vector3D vector3D = originalValues;
  itk::Vector<ScalarType, 3> itkVector = valuesToCopy;

  vector3D = itkVector;

  MITK_TEST_CONDITION(vector3D == itkVector, "itk vector assigned to mitk vector")
  MITK_TEST_CONDITION(vector3D == valuesToCopy, "correct values were assigned")
}

static void Test_itk2Mitk_floatCompatibility(void)
{
  Vector3D vector3D = originalValues;
  itk::Vector<float, 3> itkVector = valuesToCopyFloat;

  vector3D = itkVector;

  MITK_TEST_CONDITION(vector3D == itkVector, "itk float vector assigned to mitk vector")

  // test for correct values needs a little more love than in other cases
  // since Equal cannot compare arrays/vectors of different type
  bool correctValuesAssigned = true;
  for (int var = 0; var < 3; ++var) {
      correctValuesAssigned = correctValuesAssigned
          && Equal(vector3D[var], valuesToCopyFloat[var]);
  }
  MITK_TEST_CONDITION(correctValuesAssigned, "correct values were assigned")
}

static void Test_Mitk2itk_Compatibility(void)
{
  Vector3D vector3D = valuesToCopy;
  itk::Vector<ScalarType, 3> itkVector = originalValues;

  itkVector = vector3D;

  MITK_TEST_CONDITION(vector3D == itkVector, "mitk vector assigned to itk vector")
  MITK_TEST_CONDITION(itkVector == valuesToCopy, "correct values were assigned")
}

static void Test_Vnl2Mitk_VectorFixedCompatibility()
{

  mitk::Vector3D vector3D = originalValues;
  vnl_vector_fixed<ScalarType, 3> vnlVectorFixed(valuesToCopy);

  vector3D = vnlVectorFixed;

  MITK_TEST_CONDITION( vector3D.GetVnlVector() == vnlVectorFixed, "vnl_vector_fixed assigned to mitk vector")
  MITK_TEST_CONDITION( vector3D == valuesToCopy, "correct values were assigned" )
}

static void Test_Vnl2Mitk_VectorCompatibility()
{

  mitk::Vector3D vector3D = originalValues;
  vnl_vector<ScalarType> vnlVector(3);
  vnlVector.set(valuesToCopy);

  vector3D = vnlVector;

  MITK_TEST_CONDITION( vector3D.GetVnlVector() == vnlVector, "vnl_vector assigned to mitk vector")
  MITK_TEST_CONDITION( vector3D == valuesToCopy, "correct values were assigned" )
}

/**
 * tests if constructing a mitk::Vector using a shorter in size vnl_vector is handled properly
 */
static void Test_Vnl2Mitk_ShortVectorCompatibility()
{
  ScalarType shorterValuesToCopy[] = {4.12345678910, 5.10987654321};
  mitk::Vector3D vector3D = originalValues;
  vnl_vector<ScalarType> vnlVector(2);
  vnlVector.set(shorterValuesToCopy);

  vector3D = vnlVector;

  bool correctValuesInVector3D = true;
  for (int var = 0; var < 2; ++var) {
    correctValuesInVector3D = correctValuesInVector3D &&
        (vector3D[var] && shorterValuesToCopy[var]);
  }
  correctValuesInVector3D = correctValuesInVector3D && (vector3D[2] == 0.0);

  MITK_TEST_CONDITION(correctValuesInVector3D, "shorter vnl vector correctly assigned to mitk vector" )
}

/**
 * tests if constructing a mitk::Vector using a large in size vnl_vector is handled properly
 */
static void Test_Vnl2Mitk_LargeVectorCompatibility()
{
  ScalarType largerValuesToCopy[] = {4.12345678910, 5.10987654321, 6.123456789132456, 7.123456987789456};
  mitk::Vector3D vector3D = originalValues;
  vnl_vector<ScalarType> vnlVector(4);
  vnlVector.set(largerValuesToCopy);

  vector3D = vnlVector;

  bool correctValuesInVector3D = true;
  for (int var = 0; var < 3; ++var) {
    correctValuesInVector3D = correctValuesInVector3D &&
        (vector3D[var] && largerValuesToCopy[var]);
  }

  MITK_TEST_CONDITION(correctValuesInVector3D, "larger vnl vector correctly assigned to mitk vector" )
}

/**
* Test the conversions from and to the mitk vector type
*/
int mitkTypeVectorConversionTest(int /*argc*/ , char* /*argv*/[])
{
  // always start with this!
  MITK_TEST_BEGIN("VectorConversionTest")

  Test_mitk2Mitk_DifferntTypeCompatibility();

  Test_itk2Mitk_Compatibility();
  Test_itk2Mitk_floatCompatibility();

  Test_Mitk2itk_Compatibility();

  Test_Vnl2Mitk_VectorFixedCompatibility();

  Test_Vnl2Mitk_VectorCompatibility();
  Test_Vnl2Mitk_ShortVectorCompatibility();
  Test_Vnl2Mitk_LargeVectorCompatibility();

  MITK_TEST_END()

}
<commit_msg>Refactored static function names +  added one test to ensure correct conversion between mitk::Vector<float, 3> 2 itk::Vector<double, 3><commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include <iostream>

#include "itkVector.h"

#include <vnl/vnl_vector_ref.h>
#include <vnl/vnl_vector_fixed_ref.h>
#include "vnl/vnl_math.h"

#include "mitkTestingMacros.h"
#include "mitkTypeBasics.h"
#include "mitkVector.h"
#include "mitkTypes.h" // for Equals

using namespace mitk;

/**
 * these private variables are used in the test functions
 *
 * The variable which should be copied into is set to its original value.
 * The value which should be copied is set to valuesToCopy.
 *
 * Then the copying takes place. The test is successful, if the variable which
 * should be copied into holds the valuesToCopy afterwards and is equal to the
 * vector which should be copied.
 */
static const ScalarType originalValues[]      =  {1.123456789987, 2.789456321456, 3.123654789987456};
static const float      originalValuesFloat[] =  {1.123456789987, 2.789456321456, 3.123654789987456};

static const ScalarType valuesToCopy[]        =  {4.654789123321, 5.987456789321, 6.321654987789546};
static const float      valuesToCopyFloat[]   =  {4.654789123321, 5.987456789321, 6.321654987789546};

static void Test_mitk2mitk_DifferntTypeCompatibility(void)
{
  mitk::Vector<float, 3>  floatVector3D  = originalValuesFloat;
  mitk::Vector<double, 3> doubleVector3D = valuesToCopy;

  floatVector3D = doubleVector3D;

  MITK_TEST_CONDITION(floatVector3D == doubleVector3D, "mitk double vector assigned to mitk float vector")

  // test for correct values needs a little more love than in other cases
  // since Equal cannot compare arrays/vectors of different type
  bool correctValuesAssigned = true;
  for (int var = 0; var < 3; ++var) {
      correctValuesAssigned = correctValuesAssigned
          && Equal(floatVector3D[var], valuesToCopy[var], vnl_math::float_eps * 10.0);
  }
  MITK_TEST_CONDITION(correctValuesAssigned, "correct values were assigned within float accuracy")
}

static void Test_itk2mitk_Compatibility(void)
{
  Vector3D vector3D = originalValues;
  itk::Vector<ScalarType, 3> itkVector = valuesToCopy;

  vector3D = itkVector;

  MITK_TEST_CONDITION(vector3D == itkVector, "itk vector assigned to mitk vector")
  MITK_TEST_CONDITION(vector3D == valuesToCopy, "correct values were assigned")
}

static void Test_itk2mitk_floatCompatibility(void)
{
  Vector3D vector3D = originalValues;
  itk::Vector<float, 3> itkVector = valuesToCopyFloat;

  vector3D = itkVector;

  MITK_TEST_CONDITION(vector3D == itkVector, "itk float vector assigned to mitk double vector")

  // test for correct values needs a little more love than in other cases
  // since Equal cannot compare arrays/vectors of different type
  bool correctValuesAssigned = true;
  for (int var = 0; var < 3; ++var) {
      correctValuesAssigned = correctValuesAssigned
          && Equal(vector3D[var], valuesToCopyFloat[var]);
  }
  MITK_TEST_CONDITION(correctValuesAssigned, "correct values were assigned")
}

static void Test_mitk2itk_Compatibility(void)
{
  Vector3D vector3D = valuesToCopy;
  itk::Vector<ScalarType, 3> itkVector = originalValues;

  itkVector = vector3D;

  MITK_TEST_CONDITION(vector3D == itkVector, "mitk vector assigned to itk vector")
  MITK_TEST_CONDITION(itkVector == valuesToCopy, "correct values were assigned")
}

static void Test_mitk2itk_floatCompatibility(void)
{
  itk::Vector<double,3> itkDoubleVector = originalValues;
  mitk::Vector<float, 3> mitkFloatVector = valuesToCopyFloat;

  itkDoubleVector = mitkFloatVector;

  MITK_TEST_CONDITION(itkDoubleVector == mitkFloatVector, "mitk float vector assigned to itk double vector")

  // test for correct values needs a little more love than in other cases
  // since Equal cannot compare arrays/vectors of different type
  bool correctValuesAssigned = true;
  for (int var = 0; var < 3; ++var) {
      correctValuesAssigned = correctValuesAssigned
          && Equal(itkDoubleVector[var], valuesToCopyFloat[var]);
  }
  MITK_TEST_CONDITION(correctValuesAssigned, "correct values were assigned")
}

static void Test_vnl2mitk_VectorFixedCompatibility()
{

  mitk::Vector3D vector3D = originalValues;
  vnl_vector_fixed<ScalarType, 3> vnlVectorFixed(valuesToCopy);

  vector3D = vnlVectorFixed;

  MITK_TEST_CONDITION( vector3D.GetVnlVector() == vnlVectorFixed, "vnl_vector_fixed assigned to mitk vector")
  MITK_TEST_CONDITION( vector3D == valuesToCopy, "correct values were assigned" )
}

static void Test_vnl2mitk_VectorCompatibility()
{

  mitk::Vector3D vector3D = originalValues;
  vnl_vector<ScalarType> vnlVector(3);
  vnlVector.set(valuesToCopy);

  vector3D = vnlVector;

  MITK_TEST_CONDITION( vector3D.GetVnlVector() == vnlVector, "vnl_vector assigned to mitk vector")
  MITK_TEST_CONDITION( vector3D == valuesToCopy, "correct values were assigned" )
}

/**
 * tests if constructing a mitk::Vector using a shorter in size vnl_vector is handled properly
 */
static void Test_vnl2mitk_ShortVectorCompatibility()
{
  ScalarType shorterValuesToCopy[] = {4.12345678910, 5.10987654321};
  mitk::Vector3D vector3D = originalValues;
  vnl_vector<ScalarType> vnlVector(2);
  vnlVector.set(shorterValuesToCopy);

  vector3D = vnlVector;

  bool correctValuesInVector3D = true;
  for (int var = 0; var < 2; ++var) {
    correctValuesInVector3D = correctValuesInVector3D &&
        (vector3D[var] && shorterValuesToCopy[var]);
  }
  correctValuesInVector3D = correctValuesInVector3D && (vector3D[2] == 0.0);

  MITK_TEST_CONDITION(correctValuesInVector3D, "shorter vnl vector correctly assigned to mitk vector" )
}

/**
 * tests if constructing a mitk::Vector using a large in size vnl_vector is handled properly
 */
static void Test_vnl2mitk_LargeVectorCompatibility()
{
  ScalarType largerValuesToCopy[] = {4.12345678910, 5.10987654321, 6.123456789132456, 7.123456987789456};
  mitk::Vector3D vector3D = originalValues;
  vnl_vector<ScalarType> vnlVector(4);
  vnlVector.set(largerValuesToCopy);

  vector3D = vnlVector;

  bool correctValuesInVector3D = true;
  for (int var = 0; var < 3; ++var) {
    correctValuesInVector3D = correctValuesInVector3D &&
        (vector3D[var] && largerValuesToCopy[var]);
  }

  MITK_TEST_CONDITION(correctValuesInVector3D, "larger vnl vector correctly assigned to mitk vector" )
}

/**
* Test the conversions from and to the mitk vector type
*/
int mitkTypeVectorConversionTest(int /*argc*/ , char* /*argv*/[])
{
  // always start with this!
  MITK_TEST_BEGIN("VectorConversionTest")

  Test_mitk2mitk_DifferntTypeCompatibility();

  Test_itk2mitk_Compatibility();
  Test_itk2mitk_floatCompatibility();

  Test_mitk2itk_Compatibility();
  Test_mitk2itk_floatCompatibility();

  Test_vnl2mitk_VectorFixedCompatibility();

  Test_vnl2mitk_VectorCompatibility();
  Test_vnl2mitk_ShortVectorCompatibility();
  Test_vnl2mitk_LargeVectorCompatibility();

  MITK_TEST_END()

}
<|endoftext|>


<commit_before>/** Copyright (C) 2016, 2017 European Spallation Source ERIC */

#include <common/DetectorModuleRegister.h>
#include <common/Log.h>
#include <dlfcn.h>
#include <efu/Loader.h>
#include <iostream>
#include <string.h>
#include <string>

Loader::~Loader() {
  LOG(INIT, Sev::Debug, "Loader destructor called");
  // Remove pointer before closing the handle to prevent accessing freed memory
  unloadPlugin();
}

void Loader::unloadPlugin() {
  ParserPopulator = nullptr;
  if (nullptr != handle) {
    dlclose(handle);
  }
}

bool Loader::loadPlugin(const std::string lib) {
  try {
    auto &FoundModule = DetectorModuleRegistration::find(lib);
    ParserPopulator = FoundModule.CLISetup;
    myFactory = FoundModule.DetectorFactory.get();
    LOG(INIT, Sev::Info, "Loaded statically linked detector module.");
    return true;
  } catch (std::runtime_error &Error) {
    LOG(INIT, Sev::Notice, "Unable to find statically linked detector module with "
        "name\"{}\". Attempting to open external plugin.",
           lib);
  }
  std::vector<std::string> PossibleSuffixes{"", ".so", ".dll", ".dylib"};

  for (auto &CSuffix : PossibleSuffixes) {
    std::string TestLibName = "./" + lib + CSuffix;
    handle = dlopen(TestLibName.c_str(), RTLD_NOW);
    if (handle != nullptr) {
      LOG(INIT, Sev::Info, "Loaded library \"{}\".",
            TestLibName);
      break;
    }
    else {
      LOG(INIT, Sev::Warning, "Could not open library {}: {}", TestLibName,
          dlerror());
    }
  }
  if (handle == nullptr) {
    LOG(INIT, Sev::Error, "All variations of DL failed.");
    return false;
  }

  if (!(myFactory = (DetectorFactoryBase *)dlsym(handle, "Factory"))) {
    LOG(INIT, Sev::Error, "Could not find Factory in {}", lib);
    return false;
  }

  PopulateCLIParser *tempParserPopulator =
      (PopulateCLIParser *)dlsym(handle, "PopulateParser");
  if (nullptr == tempParserPopulator) {
    LOG(INIT, Sev::Warning, "Unable to find function to populate CLI parser in {}",
           lib);
  } else {
    if (nullptr == tempParserPopulator->Function) {
      LOG(INIT, Sev::Warning, "Function to populate CLI parser not set");
    } else {
      ParserPopulator = tempParserPopulator->Function;
    }
  }
  return true;
}

bool Loader::IsOk() {
  return not (myFactory == nullptr);
}

std::shared_ptr<Detector> Loader::createDetector(BaseSettings settings) {
  return myFactory->create(settings);
}
<commit_msg>quick fix for loader to support absolue and relative paths (#195)<commit_after>/** Copyright (C) 2016, 2017 European Spallation Source ERIC */

#include <common/DetectorModuleRegister.h>
#include <common/Log.h>
#include <dlfcn.h>
#include <efu/Loader.h>
#include <iostream>
#include <string.h>
#include <string>

Loader::~Loader() {
  LOG(INIT, Sev::Debug, "Loader destructor called");
  // Remove pointer before closing the handle to prevent accessing freed memory
  unloadPlugin();
}

void Loader::unloadPlugin() {
  ParserPopulator = nullptr;
  if (nullptr != handle) {
    dlclose(handle);
  }
}

bool Loader::loadPlugin(const std::string lib) {
  try {
    auto &FoundModule = DetectorModuleRegistration::find(lib);
    ParserPopulator = FoundModule.CLISetup;
    myFactory = FoundModule.DetectorFactory.get();
    LOG(INIT, Sev::Info, "Loaded statically linked detector module.");
    return true;
  } catch (std::runtime_error &Error) {
    LOG(INIT, Sev::Notice, "Unable to find statically linked detector module with "
        "name\"{}\". Attempting to open external plugin.",
           lib);
  }
  std::vector<std::string> PossibleSuffixes{"", ".so", ".dll", ".dylib"};

  for (auto &CSuffix : PossibleSuffixes) {
    // allow both absolute and relative path
    std::string Prefix = (lib[0] == '/') ? "" : "./";
    std::string TestLibName = Prefix + lib + CSuffix;
    handle = dlopen(TestLibName.c_str(), RTLD_NOW);
    if (handle != nullptr) {
      LOG(INIT, Sev::Info, "Loaded library \"{}\".",
            TestLibName);
      break;
    }
    else {
      LOG(INIT, Sev::Warning, "Could not open library {}: {}", TestLibName,
          dlerror());
    }
  }
  if (handle == nullptr) {
    LOG(INIT, Sev::Error, "All variations of DL failed.");
    return false;
  }

  if (!(myFactory = (DetectorFactoryBase *)dlsym(handle, "Factory"))) {
    LOG(INIT, Sev::Error, "Could not find Factory in {}", lib);
    return false;
  }

  PopulateCLIParser *tempParserPopulator =
      (PopulateCLIParser *)dlsym(handle, "PopulateParser");
  if (nullptr == tempParserPopulator) {
    LOG(INIT, Sev::Warning, "Unable to find function to populate CLI parser in {}",
           lib);
  } else {
    if (nullptr == tempParserPopulator->Function) {
      LOG(INIT, Sev::Warning, "Function to populate CLI parser not set");
    } else {
      ParserPopulator = tempParserPopulator->Function;
    }
  }
  return true;
}

bool Loader::IsOk() {
  return not (myFactory == nullptr);
}

std::shared_ptr<Detector> Loader::createDetector(BaseSettings settings) {
  return myFactory->create(settings);
}
<|endoftext|>


<commit_before>#include "sound.hpp"
#include "oddlib/audio/SequencePlayer.h"
#include "gui.hpp"
#include "core/audiobuffer.hpp"
#include "logger.hpp"
#include "filesystem.hpp"

void Sound::BarLoop()
{
    printf("Bar Loop!");

    if (mTargetSong != -1)
    {
        if (mSeqPlayer->LoadSequenceData(mAliveAudio.m_LoadedSeqData[mTargetSong]) == 0)
        {
            mSeqPlayer->PlaySequence();
        }
        mTargetSong = -1;
    }
}

void Sound::ChangeTheme(FileSystem& fs, const std::deque<std::string>& parts)
{
    try
    {
        const std::string lvlFileName = parts[0];
        Oddlib::LvlArchive archive(fs.ResourceExists(lvlFileName)->Open(lvlFileName));
        mAliveAudio.LoadAllFromLvl(archive, parts[1], parts[2]); // vab, bsq
    }
    catch (const std::exception& ex)
    {
        LOG_ERROR("Audio error: " << ex.what());
    }
}

Sound::Sound(GameData& gameData, IAudioController& audioController, FileSystem& fs)
    : mGameData(gameData), mAudioController(audioController), mFs(fs)
{
    mAudioController.AddPlayer(&mAliveAudio);
}

Sound::~Sound()
{
    mAudioController.RemovePlayer(&mAliveAudio);
}

void Sound::Update()
{
    if (mSeqPlayer)
    {
        mSeqPlayer->m_PlayerThreadFunction();
    }
}

void Sound::Render(GuiContext *gui, int /*w*/, int /*h*/)
{
    static bool bSet = false;
    if (!bSet)
    {
        try
        {
            // Currently requires sounds.dat to be available from the get-go, so make
            // this failure non-fatal
            mAliveAudio.AliveInitAudio(mFs);
        }
        catch (const std::exception& ex)
        {
            LOG_ERROR("Audio init failure: " << ex.what());
        }

        bSet = true;
        auto themes = mAliveAudio.m_Config.get<jsonxx::Array>("themes");
        for (auto i = 0u; i < themes.size(); i++)
        {
            auto theme = themes.get<jsonxx::Object>(i);

            const std::string lvlFileName = theme.get<jsonxx::String>("lvl", "null") + ".LVL";
            auto res = mFs.ResourceExists(lvlFileName);
            if (res)
            {
                Oddlib::LvlArchive archive(res->Open(lvlFileName));
                auto vabName = theme.get<jsonxx::String>("vab", "null");
                auto bsqName = theme.get<jsonxx::String>("seq", "null");

                Oddlib::LvlArchive::File* file = archive.FileByName(bsqName);
                for (auto j = 0u; j < file->ChunkCount(); j++)
                {
                    mThemes.push_back(lvlFileName + "!" + vabName + "!" + bsqName + "!" + std::to_string(j));
                }
            }
        }
    }

    gui->next_window_pos = V2i(320, 250);
    gui_begin_window(gui, "Sound", V2i(250, 400));

    static int selectedIndex = 0;
    for (size_t i = 0; i < mThemes.size(); i++)
    {
        //if (ImGui::Selectable(mThemes[i].c_str(), static_cast<int>(i) == selectedIndex))
        if (gui_button(gui, mThemes[i].c_str()))
        {
            selectedIndex = static_cast<int>(i);
            if (selectedIndex >= 0 && selectedIndex < static_cast<int>(mThemes.size()) && !mThemes.empty())
            {
                mAudioController.SetAudioSpec(1024, AliveAudioSampleRate);
                mSeqPlayer = std::make_unique<SequencePlayer>(mAliveAudio);
                mSeqPlayer->m_QuarterCallback = [&]() { BarLoop(); };
                const auto parts = string_util::split(mThemes[selectedIndex], '!');
                int seqId = std::atoi(parts[3].c_str());
                ChangeTheme(mFs, parts);
                if (mSeqPlayer->m_PlayerState == ALIVE_SEQUENCER_FINISHED || mSeqPlayer->m_PlayerState == ALIVE_SEQUENCER_STOPPED)
                {
                    if (seqId < static_cast<int>(mAliveAudio.m_LoadedSeqData.size()) && mSeqPlayer->LoadSequenceData(mAliveAudio.m_LoadedSeqData[seqId]) == 0)
                    {
                        mSeqPlayer->PlaySequence();
                    }
                }
                else
                {
                    mTargetSong = seqId;
                }
            }
        }
    }
    gui_end_window(gui);

    gui->next_window_pos = V2i(50, 250);
    { gui_begin_window(gui, "Audio output settings", V2i(250, 300));
        gui_checkbox(gui, "Use antialiasing (not implemented)", &mAliveAudio.AntiAliasFilteringEnabled);

        if (gui_radiobutton(gui, "No interpolation", mAliveAudio.Interpolation == AudioInterpolation_none))
            mAliveAudio.Interpolation = AudioInterpolation_none;

        if (gui_radiobutton(gui, "Linear interpolation", mAliveAudio.Interpolation == AudioInterpolation_linear))
            mAliveAudio.Interpolation = AudioInterpolation_linear;

        if (gui_radiobutton(gui, "Cubic interpolation", mAliveAudio.Interpolation == AudioInterpolation_cubic))
            mAliveAudio.Interpolation = AudioInterpolation_cubic;

        if (gui_radiobutton(gui, "Hermite interpolation", mAliveAudio.Interpolation == AudioInterpolation_hermite))
            mAliveAudio.Interpolation = AudioInterpolation_hermite;

        gui_checkbox(gui, "Force reverb", &mAliveAudio.ForceReverb);
        gui_slider(gui, "Reverb mix", &mAliveAudio.ReverbMix, 0.0f, 1.0f);

        gui_checkbox(gui, "Disable resampling (= no freq changes)", &mAliveAudio.DebugDisableVoiceResampling);
    gui_end_window(gui);  }
}
<commit_msg>make lack of sounds.dat not bring everything to its death.. again<commit_after>#include "sound.hpp"
#include "oddlib/audio/SequencePlayer.h"
#include "gui.hpp"
#include "core/audiobuffer.hpp"
#include "logger.hpp"
#include "filesystem.hpp"

void Sound::BarLoop()
{
    printf("Bar Loop!");

    if (mTargetSong != -1)
    {
        if (mSeqPlayer->LoadSequenceData(mAliveAudio.m_LoadedSeqData[mTargetSong]) == 0)
        {
            mSeqPlayer->PlaySequence();
        }
        mTargetSong = -1;
    }
}

void Sound::ChangeTheme(FileSystem& fs, const std::deque<std::string>& parts)
{
    try
    {
        const std::string lvlFileName = parts[0];
        Oddlib::LvlArchive archive(fs.ResourceExists(lvlFileName)->Open(lvlFileName));
        mAliveAudio.LoadAllFromLvl(archive, parts[1], parts[2]); // vab, bsq
    }
    catch (const std::exception& ex)
    {
        LOG_ERROR("Audio error: " << ex.what());
    }
}

Sound::Sound(GameData& gameData, IAudioController& audioController, FileSystem& fs)
    : mGameData(gameData), mAudioController(audioController), mFs(fs)
{
    mAudioController.AddPlayer(&mAliveAudio);
}

Sound::~Sound()
{
    mAudioController.RemovePlayer(&mAliveAudio);
}

void Sound::Update()
{
    if (mSeqPlayer)
    {
        mSeqPlayer->m_PlayerThreadFunction();
    }
}

void Sound::Render(GuiContext *gui, int /*w*/, int /*h*/)
{
    static bool bSet = false;
    if (!bSet)
    {
        try
        {
            bSet = true;

            // Currently requires sounds.dat to be available from the get-go, so make
            // this failure non-fatal
            mAliveAudio.AliveInitAudio(mFs);

            auto themes = mAliveAudio.m_Config.get<jsonxx::Array>("themes");
            for (auto i = 0u; i < themes.size(); i++)
            {
                auto theme = themes.get<jsonxx::Object>(i);

                const std::string lvlFileName = theme.get<jsonxx::String>("lvl", "null") + ".LVL";
                auto res = mFs.ResourceExists(lvlFileName);
                if (res)
                {
                    Oddlib::LvlArchive archive(res->Open(lvlFileName));
                    auto vabName = theme.get<jsonxx::String>("vab", "null");
                    auto bsqName = theme.get<jsonxx::String>("seq", "null");

                    Oddlib::LvlArchive::File* file = archive.FileByName(bsqName);
                    for (auto j = 0u; j < file->ChunkCount(); j++)
                    {
                        mThemes.push_back(lvlFileName + "!" + vabName + "!" + bsqName + "!" + std::to_string(j));
                    }
                }
            }
        }
        catch (const std::exception& ex)
        {
            LOG_ERROR("Audio init failure: " << ex.what());
        }
    }

    gui->next_window_pos = V2i(320, 250);
    gui_begin_window(gui, "Sound", V2i(250, 400));

    static int selectedIndex = 0;
    for (size_t i = 0; i < mThemes.size(); i++)
    {
        //if (ImGui::Selectable(mThemes[i].c_str(), static_cast<int>(i) == selectedIndex))
        if (gui_button(gui, mThemes[i].c_str()))
        {
            selectedIndex = static_cast<int>(i);
            if (selectedIndex >= 0 && selectedIndex < static_cast<int>(mThemes.size()) && !mThemes.empty())
            {
                mAudioController.SetAudioSpec(1024, AliveAudioSampleRate);
                mSeqPlayer = std::make_unique<SequencePlayer>(mAliveAudio);
                mSeqPlayer->m_QuarterCallback = [&]() { BarLoop(); };
                const auto parts = string_util::split(mThemes[selectedIndex], '!');
                int seqId = std::atoi(parts[3].c_str());
                ChangeTheme(mFs, parts);
                if (mSeqPlayer->m_PlayerState == ALIVE_SEQUENCER_FINISHED || mSeqPlayer->m_PlayerState == ALIVE_SEQUENCER_STOPPED)
                {
                    if (seqId < static_cast<int>(mAliveAudio.m_LoadedSeqData.size()) && mSeqPlayer->LoadSequenceData(mAliveAudio.m_LoadedSeqData[seqId]) == 0)
                    {
                        mSeqPlayer->PlaySequence();
                    }
                }
                else
                {
                    mTargetSong = seqId;
                }
            }
        }
    }
    gui_end_window(gui);

    gui->next_window_pos = V2i(50, 250);
    { gui_begin_window(gui, "Audio output settings", V2i(250, 300));
        gui_checkbox(gui, "Use antialiasing (not implemented)", &mAliveAudio.AntiAliasFilteringEnabled);

        if (gui_radiobutton(gui, "No interpolation", mAliveAudio.Interpolation == AudioInterpolation_none))
            mAliveAudio.Interpolation = AudioInterpolation_none;

        if (gui_radiobutton(gui, "Linear interpolation", mAliveAudio.Interpolation == AudioInterpolation_linear))
            mAliveAudio.Interpolation = AudioInterpolation_linear;

        if (gui_radiobutton(gui, "Cubic interpolation", mAliveAudio.Interpolation == AudioInterpolation_cubic))
            mAliveAudio.Interpolation = AudioInterpolation_cubic;

        if (gui_radiobutton(gui, "Hermite interpolation", mAliveAudio.Interpolation == AudioInterpolation_hermite))
            mAliveAudio.Interpolation = AudioInterpolation_hermite;

        gui_checkbox(gui, "Force reverb", &mAliveAudio.ForceReverb);
        gui_slider(gui, "Reverb mix", &mAliveAudio.ReverbMix, 0.0f, 1.0f);

        gui_checkbox(gui, "Disable resampling (= no freq changes)", &mAliveAudio.DebugDisableVoiceResampling);
    gui_end_window(gui);  }
}
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef HTTP_COMMON_HPP
#define HTTP_COMMON_HPP

#include <delegate>
#include <experimental/string_view>
#include <memory>
#include <uri>
#include <utility>
#include <vector>

namespace http {

using URI = uri::URI;

using Header_set = std::vector<std::pair<std::string, std::string>>;

class Request;
using Request_ptr = std::unique_ptr<Request>;

class Response;
using Response_ptr = std::unique_ptr<Response>;

class Error;
using Response_handler = delegate<void(Error, Response_ptr)>;

} //< namespace http

#endif //< HTTP_COMMON_HPP
<commit_msg>http: This seems to fix delegates sometimes ending up as nullptr in client<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef HTTP_COMMON_HPP
#define HTTP_COMMON_HPP

#include <delegate>
#include <experimental/string_view>
#include <memory>
#include <uri>
#include <utility>
#include <vector>

namespace http {

using URI = uri::URI;

using Header_set = std::vector<std::pair<std::string, std::string>>;

class Request;
using Request_ptr = std::unique_ptr<Request>;

class Response;
using Response_ptr = std::unique_ptr<Response>;

class Error;
using Response_handler = delegate<void(Error, Response_ptr), spec::dynamic>;

} //< namespace http

#endif //< HTTP_COMMON_HPP
<|endoftext|>


<commit_before>/**
    TimeType.cpp
    Auto-generated code - do not modify.
    thinglang C++ transpiler, 0.0.0
**/

#include "../InternalTypes.h"
#include "../../execution/Program.h"

/**
Methods of TimeType
**/

void TimeType::__constructor__() {
    Program::push(Program::create<TimeInstance>());
}

void TimeType::now() {
    Program::push(Program::create<NumberInstance>(std::chrono::system_clock::now().time_since_epoch().count()));
}

<commit_msg>Use standard time() call for Time.now()<commit_after>/**
    TimeType.cpp
    Auto-generated code - do not modify.
    thinglang C++ transpiler, 0.0.0
**/

#include "../InternalTypes.h"
#include "../../execution/Program.h"

/**
Methods of TimeType
**/

void TimeType::__constructor__() {
    Program::push(Program::create<TimeInstance>());
}

void TimeType::now() {
    Program::push(Program::create<NumberInstance>(time(nullptr)));
}

<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <cstdlib>

#include <stdio.h>
#include <getopt.h>

#include "boost/program_options.hpp"

#include "libutil/exceptions.h"

#include "libsyntax/driver.h"
#include "libsyntax/types.h"
#include "libsyntax/ast_dump_visitor.h"
#include "libsyntax/parser.tab.h"
#include "libsyntax/ast_dump_visitor.h"

#include "libmiddle/typecheck_visitor.h"

#include "libinterpreter/execution_visitor.h"
#include "libinterpreter/execution_context.h"
#include "libinterpreter/value.h"

// driver must be global, because it is needed for YY_INPUT
// defined in src/libsyntax/driver.cpp
extern Driver *global_driver;

enum OptionValues {
  NO_OPTIONS = 0,
  HELP = 1,
  DUMP_AST = (1 << 1),
  ERROR = (1 << 2)
};

struct arguments {
  int flags;
  std::string filename;
};

struct arguments parse_cmd_args(int argc, char *argv[]) {
  int dump_ast;
  struct option long_options[] = {
       {"help", no_argument, 0, 'h'},
       {"dump-ast", no_argument, &dump_ast, 1},
       {0, 0, 0, 0}
  };

  int option_index = 0;
  int opt;
  int flags = 0;

  while ((opt = getopt_long(argc, argv, "h",
                            long_options, &option_index)) != -1) {
    switch(opt) {
      case 0:
        if (option_index == 1) {
          flags |= OptionValues::DUMP_AST;
        } else {
          flags |= OptionValues::ERROR;
        }
        break;
      case 'h':
        flags |= OptionValues::HELP;
        break;
      case '?':
        flags |= OptionValues::ERROR;
        /* getopt_long already printed an error message. */
        break;
      default:
        flags |= OptionValues::ERROR;
        break;
    }
  }
  struct arguments opts;
  opts.flags = flags;

  if (optind == argc-1) {
    opts.filename = std::string(argv[optind]);
  }
  return opts;
}

int main (int argc, char *argv[]) {
  int res = 0;
  struct arguments opts = parse_cmd_args(argc, argv);

  if ((opts.flags & OptionValues::ERROR) != 0) {
    std::cerr << "There has been an error" << std::endl;
    std::exit(EXIT_FAILURE);
  }

  if (opts.filename.size() == 0) {
    std::cerr << "No filename provided" << std::endl;
    return EXIT_FAILURE;
  }
  //
  // Setup the driver
  Driver driver;
  global_driver = &driver;

  switch (opts.flags) {
    case OptionValues::DUMP_AST: {
      if (driver.parse(opts.filename) == nullptr) {
        std::cerr << "Error parsing file" << std::endl;
        delete driver.result;
        return EXIT_FAILURE;
      }

      AstDumpVisitor dump_visitor;
      AstWalker<AstDumpVisitor, bool> dump_walker(dump_visitor);
      dump_walker.walk_specification(driver.result);
      std::cout << dump_visitor.get_dump();
    }
    case OptionValues::NO_OPTIONS: {
      if (driver.parse(opts.filename) == nullptr) {
        std::cerr << "Error parsing file " << driver.result << std::endl;
        delete driver.result;
        return EXIT_FAILURE;
      }

      TypecheckVisitor typecheck_visitor(driver);
      AstWalker<TypecheckVisitor, Type> typecheck_walker(typecheck_visitor);
      typecheck_walker.walk_specification(driver.result);
      if (!driver.ok()) {
        res = 1;
      } else {
        ExecutionContext ctx(driver.current_symbol_table);
        ExecutionVisitor visitor(ctx, driver.get_init_rule(), driver);
        ExecutionWalker walker(visitor);
        try {
          walker.run();
        } catch (const RuntimeException& ex) {
          res = EXIT_FAILURE;
        }
      }
    }
  }
  delete driver.result;

  return res;
}
<commit_msg>Add function to print help<commit_after>#include <iostream>
#include <string>
#include <cstdlib>

#include <getopt.h>

#include "libutil/exceptions.h"

#include "libsyntax/driver.h"
#include "libsyntax/types.h"
#include "libsyntax/ast_dump_visitor.h"
#include "libsyntax/parser.tab.h"
#include "libsyntax/ast_dump_visitor.h"

#include "libmiddle/typecheck_visitor.h"

#include "libinterpreter/execution_visitor.h"
#include "libinterpreter/execution_context.h"
#include "libinterpreter/value.h"

// driver must be global, because it is needed for YY_INPUT
// defined in src/libsyntax/driver.cpp
extern Driver *global_driver;

enum OptionValues {
  NO_OPTIONS = 0,
  HELP = 1,
  DUMP_AST = (1 << 1),
  ERROR = (1 << 2)
};

struct arguments {
  int flags;
  std::string filename;
};

struct arguments parse_cmd_args(int argc, char *argv[]) {
  int dump_ast;
  struct option long_options[] = {
       {"help", no_argument, 0, 'h'},
       {"dump-ast", no_argument, &dump_ast, 1},
       {0, 0, 0, 0}
  };

  int option_index = 0;
  int opt;
  int flags = 0;

  while ((opt = getopt_long(argc, argv, "h",
                            long_options, &option_index)) != -1) {
    switch(opt) {
      case 0:
        if (option_index == 1) {
          flags |= OptionValues::DUMP_AST;
        } else {
          flags |= OptionValues::ERROR;
        }
        break;
      case 'h':
        flags |= OptionValues::HELP;
        break;
      case '?':
        flags |= OptionValues::ERROR;
        /* getopt_long already printed an error message. */
        break;
      default:
        flags |= OptionValues::ERROR;
        break;
    }
  }
  struct arguments opts;
  opts.flags = flags;

  if (optind == argc-1) {
    opts.filename = std::string(argv[optind]);
  }
  return opts;
}

void print_help() {
  std::cout << "USAGE: casmi [OPTIONS] <filename>" << std::endl;
  std::cout << std::endl;
  std::cout << "OPTIONS:" << std::endl;
  std::cout << "  -h, --help" << "\t\t" << "shows command line options" << std::endl;
  std::cout << "  --dump-ast" << "\t\t" << "dumps the AST as dot graph" << std::endl;
}

int main (int argc, char *argv[]) {
  int res = 0;
  struct arguments opts = parse_cmd_args(argc, argv);

  if ((opts.flags & OptionValues::ERROR) != 0) {
    std::cerr << "There has been an error" << std::endl;
    return EXIT_FAILURE;
  }

  if (opts.flags == OptionValues::HELP) {
    print_help();
    return EXIT_SUCCESS;
  }
  if (opts.filename.size() == 0) {
    std::cerr << "No filename provided" << std::endl;
    return EXIT_FAILURE;
  }
  //
  // Setup the driver
  Driver driver;
  global_driver = &driver;

  switch (opts.flags) {
    case OptionValues::DUMP_AST: {
      if (driver.parse(opts.filename) == nullptr) {
        std::cerr << "Error parsing file" << std::endl;
        res = EXIT_FAILURE;
        break;
      }

      AstDumpVisitor dump_visitor;
      AstWalker<AstDumpVisitor, bool> dump_walker(dump_visitor);
      dump_walker.walk_specification(driver.result);
      std::cout << dump_visitor.get_dump();
      res = EXIT_SUCCESS;
      break;
    }
    case OptionValues::NO_OPTIONS: {
      if (driver.parse(opts.filename) == nullptr) {
        std::cerr << "Error parsing file " << driver.result << std::endl;
        res = EXIT_FAILURE;
        break;
      }

      TypecheckVisitor typecheck_visitor(driver);
      AstWalker<TypecheckVisitor, Type> typecheck_walker(typecheck_visitor);
      typecheck_walker.walk_specification(driver.result);
      if (!driver.ok()) {
        res = EXIT_FAILURE;
      } else {
        ExecutionContext ctx(driver.current_symbol_table);
        ExecutionVisitor visitor(ctx, driver.get_init_rule(), driver);
        ExecutionWalker walker(visitor);
        try {
          walker.run();
          res = EXIT_SUCCESS;
        } catch (const RuntimeException& ex) {
          res = EXIT_FAILURE;
        }
      }
      break;
    }
  }
  delete driver.result;

  return res;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the Qt Assistant of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qhelpenginecore.h"
#include "qhelpsearchengine.h"
#include "qhelpsearchquerywidget.h"
#include "qhelpsearchresultwidget.h"

#if defined(QT_CLUCENE_SUPPORT)
#   include "qhelpsearchindexreader_clucene_p.h"
#   include "qhelpsearchindexwriter_clucene_p.h"
#else
#   include "qhelpsearchindexreader_default_p.h"
#   include "qhelpsearchindexwriter_default_p.h"
#endif

#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QVariant>
#include <QtCore/QThread>
#include <QtCore/QPointer>

QT_BEGIN_NAMESPACE

#if defined(QT_CLUCENE_SUPPORT)
    using namespace qt::fulltextsearch::clucene;
#else
    using namespace qt::fulltextsearch::std;
#endif

class QHelpSearchEnginePrivate : public QObject
{
    Q_OBJECT

signals:
    void indexingStarted();
    void indexingFinished();

    void searchingStarted();
    void searchingFinished(int hits);

private:
    QHelpSearchEnginePrivate(QHelpEngineCore *helpEngine)
        : queryWidget(0)
        , resultWidget(0)
        , helpEngine(helpEngine)
    {
        hitList.clear();
        indexReader = 0;
        indexWriter = 0;
    }

    ~QHelpSearchEnginePrivate()
    {
        hitList.clear();
        delete indexReader;
        delete indexWriter;
    }

    int hitsCount() const
    {
        int count = 0;
        if (indexReader)
            count = indexReader->hitsCount();

        return count;
    }

    QList<QHelpSearchEngine::SearchHit> hits(int start, int end) const
    {
        QList<QHelpSearchEngine::SearchHit> returnValue;
        if (indexReader) {
            for (int i = start; i < end && i < hitsCount(); ++i)
                returnValue.append(indexReader->hit(i));
        }
        return returnValue;
    }

    void updateIndex(bool reindex = false)
    {
        if (helpEngine.isNull())
            return;

        if (!QFile::exists(QFileInfo(helpEngine->collectionFile()).path()))
            return;

        if (!indexWriter) {
            indexWriter = new QHelpSearchIndexWriter();

            connect(indexWriter, SIGNAL(indexingStarted()), this, SIGNAL(indexingStarted()));
            connect(indexWriter, SIGNAL(indexingFinished()), this, SIGNAL(indexingFinished()));
            connect(indexWriter, SIGNAL(indexingFinished()), this, SLOT(optimizeIndex()));
        }

        if (indexWriter) {
            indexWriter->cancelIndexing();
            indexWriter->updateIndex(helpEngine->collectionFile(),
                indexFilesFolder(), reindex);
        }
    }

    void cancelIndexing()
    {
        if (indexWriter)
            indexWriter->cancelIndexing();
    }

    void search(const QList<QHelpSearchQuery> &queryList)
    {
        if (helpEngine.isNull())
            return;

        if (!QFile::exists(QFileInfo(helpEngine->collectionFile()).path()))
            return;

        if (!indexReader) {
            indexReader = new QHelpSearchIndexReader();

            connect(indexReader, SIGNAL(searchingStarted()), this, SIGNAL(searchingStarted()));
            connect(indexReader, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int)));
        }

        if (indexReader) {
            m_queryList = queryList;
            indexReader->cancelSearching();
            indexReader->search(helpEngine->collectionFile(), indexFilesFolder(), queryList);
        }
    }

    void cancelSearching()
    {
        if (indexReader)
            indexReader->cancelSearching();
    }

    QString indexFilesFolder() const
    {
        QString indexFilesFolder = QLatin1String(".fulltextsearch");
        if (helpEngine && !helpEngine->collectionFile().isEmpty()) {
            QFileInfo fi(helpEngine->collectionFile());
            indexFilesFolder = fi.absolutePath() + QDir::separator()
                + QLatin1Char('.')
                + fi.fileName().left(fi.fileName().lastIndexOf(QLatin1String(".qhc")));
        }
        return indexFilesFolder;
    }

private slots:
    void optimizeIndex()
    {
#if defined(QT_CLUCENE_SUPPORT)
        if (indexWriter && !helpEngine.isNull()) {
            indexWriter->optimizeIndex();
        }
#endif
    }

private:
    friend class QHelpSearchEngine;

    QHelpSearchQueryWidget *queryWidget;
    QHelpSearchResultWidget *resultWidget;

    QHelpSearchIndexReader *indexReader;
    QHelpSearchIndexWriter *indexWriter;

    QPointer<QHelpEngineCore> helpEngine;
    QList<QHelpSearchEngine::SearchHit> hitList;

    QList<QHelpSearchQuery> m_queryList;
};

#include "qhelpsearchengine.moc"

/*!
    \class QHelpSearchQuery
    \since 4.4
    \inmodule QtHelp
    \brief The QHelpSearchQuery class contains the field name and the associated
    search term

    The QHelpSearchQuery class contains the field name and the associated search
    term. Depending on the field the search term might get split up into seperate
    terms to be parsed differently by the search engine.

    \sa QHelpSearchQueryWidget
*/

/*!
    \fn QHelpSearchQuery::QHelpSearchQuery()

    Constructs a new empty QHelpSearchQuery.
*/

/*!
    \fn QHelpSearchQuery::QHelpSearchQuery(FieldName field, const QStringList &wordList)

    Constructs a new QHelpSearchQuery and initializes it with the given \a field and \a wordList.
*/

/*!
    \enum QHelpSearchQuery::FieldName
    This enum type specifies the field names that are handled by the search engine.

    \value DEFAULT  the default field provided by the search widget, several terms should be
                    splitted and stored in the wordlist except search terms enclosed in quotes.
    \value FUZZY    a field only provided in use with clucene. Terms should be split in seperate
                    words and passed to the search engine.
    \value WITHOUT  a field only provided in use with clucene. Terms should be split in seperate
                    words and passed to the search engine.
    \value PHRASE   a field only provided in use with clucene. Terms should not be split in seperate
                    words.
    \value ALL      a field only provided in use with clucene. Terms should be split in seperate
                    words and passed to the search engine
    \value ATLEAST  a field only provided in use with clucene. Terms should be split in seperate
                    words and passed to the search engine
*/

/*!
    \class QHelpSearchEngine
    \since 4.4
    \inmodule QtHelp
    \brief The QHelpSearchEngine class provides access to widgets reusable
    to integrate fulltext search as well as to index and search documentation.

    Before the search engine can be used, one has to instantiate at least a
    QHelpEngineCore object that needs to be passed to the search engines constructor.
    This is required as the search engine needs to be connected to the help
    engines setupFinished() signal to know when it can start to index documentation.

    After starting the indexing process the signal indexingStarted() is emitted and
    on the end of the indexing process the indexingFinished() is emited. To stop
    the indexing one can call cancelIndexing().

    While the indexing process has finished, the search engine can now be used to search
    thru its index for a given term. To do this one may use the possibility of creating the
    QHelpSearchQuery list by self or reuse the QHelpSearchQueryWidget which has the inbuild
    functionality to set up a proper search querys list that get's passed to the search engines
    search() function.

    After the list of querys has been passed to the search engine, the signal searchingStarted()
    is emited and after the search has finished the searchingFinished() signal is emited. The
    search process can be stopped by calling cancelSearching().

    If the search succeeds, the searchingFinished() will be called with the search hits count,
    which can be reused to fetch the search hits from the search engine. Calling the hits()
    function with the range of hits you would like to get will return a list of the requested
    SearchHits. They basically constist at the moment of a pair of strings where the values
    of that pair are the documentation file path and the page title.

    To display the given hits use the QHelpSearchResultWidget or build up your own one if you need
    more advanced functionality. Note that the QHelpSearchResultWidget can not be instantiated
    directly, you must retrieve the widget from the search engine in use as all connections will be
    established for you by the widget itself.
*/

/*!
    \fn void QHelpSearchEngine::indexingStarted()

    This signal is emitted when indexing process is started.
*/

/*!
    \fn void QHelpSearchEngine::indexingFinished()

    This signal is emitted when the indexing process is complete.
*/

/*!
    \fn void QHelpSearchEngine::searchingStarted()

    This signal is emitted when the search process is started.
*/

/*!
    \fn void QHelpSearchEngine::searchingFinished(int hits)

    This signal is emitted when the search process is complete.
    The hit count is stored in \a hits.
*/

/*!
    Constructs a new search engine with the given \a parent. The search engine
    uses the given \a helpEngine to access the documentation that needs to be indexed.
    The QHelpEngine's setupFinished() signal is automatically connected to the
    QHelpSearchEngine's indexing function, so that new documentation will be indexed
    after the signal is emited.
*/
QHelpSearchEngine::QHelpSearchEngine(QHelpEngineCore *helpEngine, QObject *parent)
    : QObject(parent)
{
    d = new QHelpSearchEnginePrivate(helpEngine);

    connect(helpEngine, SIGNAL(setupFinished()), this, SLOT(indexDocumentation()));

    connect(d, SIGNAL(indexingStarted()), this, SIGNAL(indexingStarted()));
    connect(d, SIGNAL(indexingFinished()), this, SIGNAL(indexingFinished()));
    connect(d, SIGNAL(searchingStarted()), this, SIGNAL(searchingStarted()));
    connect(d, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int)));
}

/*!
    Destructs the search engine.
*/
QHelpSearchEngine::~QHelpSearchEngine()
{
    delete d;
}

/*!
    Returns a widget to use as input widget. Depending on your search engine
    configuration you will get a different widget with more or less subwidgets.
*/
QHelpSearchQueryWidget* QHelpSearchEngine::queryWidget()
{
    if (!d->queryWidget)
        d->queryWidget = new QHelpSearchQueryWidget();

    return d->queryWidget;
}

/*!
    Returns a widget that can hold and display the search results.
*/
QHelpSearchResultWidget* QHelpSearchEngine::resultWidget()
{
    if (!d->resultWidget)
        d->resultWidget = new QHelpSearchResultWidget(this);

    return d->resultWidget;
}

/*!
    Returns the amount of hits the search engine found.
*/
int QHelpSearchEngine::hitsCount() const
{
    return d->hitsCount();
}

/*!
    \typedef QHelpSearchEngine::SearchHit

    Typedef for QPair<QString, QString>.
    The values of that pair are the documentation file path and the page title.

    \sa hits()
*/

/*!
    Returns a list of search hits within the range of \a start \a end.
*/
QList<QHelpSearchEngine::SearchHit> QHelpSearchEngine::hits(int start, int end) const
{
   return d->hits(start, end);
}

/*!
    Returns the list of queries last searched for.
    \since 4.5
*/
QList<QHelpSearchQuery> QHelpSearchEngine::query() const
{
    return d->m_queryList;
}

/*!
    Forces the search engine to reindex all documentation files.
*/
void QHelpSearchEngine::reindexDocumentation()
{
    d->updateIndex(true);
}

/*!
    Stops the indexing process.
*/
void QHelpSearchEngine::cancelIndexing()
{
    d->cancelIndexing();
}

/*!
    Stops the search process.
*/
void QHelpSearchEngine::cancelSearching()
{
    d->cancelSearching();
}

/*!
    Starts the search process using the given list of querys \a queryList
    build by the search field name and the values to search for.
*/
void QHelpSearchEngine::search(const QList<QHelpSearchQuery> &queryList)
{
    d->search(queryList);
}

void QHelpSearchEngine::indexDocumentation()
{
    d->updateIndex();
}

QT_END_NAMESPACE
<commit_msg>Spelling in docs.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the Qt Assistant of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qhelpenginecore.h"
#include "qhelpsearchengine.h"
#include "qhelpsearchquerywidget.h"
#include "qhelpsearchresultwidget.h"

#if defined(QT_CLUCENE_SUPPORT)
#   include "qhelpsearchindexreader_clucene_p.h"
#   include "qhelpsearchindexwriter_clucene_p.h"
#else
#   include "qhelpsearchindexreader_default_p.h"
#   include "qhelpsearchindexwriter_default_p.h"
#endif

#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QVariant>
#include <QtCore/QThread>
#include <QtCore/QPointer>

QT_BEGIN_NAMESPACE

#if defined(QT_CLUCENE_SUPPORT)
    using namespace qt::fulltextsearch::clucene;
#else
    using namespace qt::fulltextsearch::std;
#endif

class QHelpSearchEnginePrivate : public QObject
{
    Q_OBJECT

signals:
    void indexingStarted();
    void indexingFinished();

    void searchingStarted();
    void searchingFinished(int hits);

private:
    QHelpSearchEnginePrivate(QHelpEngineCore *helpEngine)
        : queryWidget(0)
        , resultWidget(0)
        , helpEngine(helpEngine)
    {
        hitList.clear();
        indexReader = 0;
        indexWriter = 0;
    }

    ~QHelpSearchEnginePrivate()
    {
        hitList.clear();
        delete indexReader;
        delete indexWriter;
    }

    int hitsCount() const
    {
        int count = 0;
        if (indexReader)
            count = indexReader->hitsCount();

        return count;
    }

    QList<QHelpSearchEngine::SearchHit> hits(int start, int end) const
    {
        QList<QHelpSearchEngine::SearchHit> returnValue;
        if (indexReader) {
            for (int i = start; i < end && i < hitsCount(); ++i)
                returnValue.append(indexReader->hit(i));
        }
        return returnValue;
    }

    void updateIndex(bool reindex = false)
    {
        if (helpEngine.isNull())
            return;

        if (!QFile::exists(QFileInfo(helpEngine->collectionFile()).path()))
            return;

        if (!indexWriter) {
            indexWriter = new QHelpSearchIndexWriter();

            connect(indexWriter, SIGNAL(indexingStarted()), this, SIGNAL(indexingStarted()));
            connect(indexWriter, SIGNAL(indexingFinished()), this, SIGNAL(indexingFinished()));
            connect(indexWriter, SIGNAL(indexingFinished()), this, SLOT(optimizeIndex()));
        }

        if (indexWriter) {
            indexWriter->cancelIndexing();
            indexWriter->updateIndex(helpEngine->collectionFile(),
                indexFilesFolder(), reindex);
        }
    }

    void cancelIndexing()
    {
        if (indexWriter)
            indexWriter->cancelIndexing();
    }

    void search(const QList<QHelpSearchQuery> &queryList)
    {
        if (helpEngine.isNull())
            return;

        if (!QFile::exists(QFileInfo(helpEngine->collectionFile()).path()))
            return;

        if (!indexReader) {
            indexReader = new QHelpSearchIndexReader();

            connect(indexReader, SIGNAL(searchingStarted()), this, SIGNAL(searchingStarted()));
            connect(indexReader, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int)));
        }

        if (indexReader) {
            m_queryList = queryList;
            indexReader->cancelSearching();
            indexReader->search(helpEngine->collectionFile(), indexFilesFolder(), queryList);
        }
    }

    void cancelSearching()
    {
        if (indexReader)
            indexReader->cancelSearching();
    }

    QString indexFilesFolder() const
    {
        QString indexFilesFolder = QLatin1String(".fulltextsearch");
        if (helpEngine && !helpEngine->collectionFile().isEmpty()) {
            QFileInfo fi(helpEngine->collectionFile());
            indexFilesFolder = fi.absolutePath() + QDir::separator()
                + QLatin1Char('.')
                + fi.fileName().left(fi.fileName().lastIndexOf(QLatin1String(".qhc")));
        }
        return indexFilesFolder;
    }

private slots:
    void optimizeIndex()
    {
#if defined(QT_CLUCENE_SUPPORT)
        if (indexWriter && !helpEngine.isNull()) {
            indexWriter->optimizeIndex();
        }
#endif
    }

private:
    friend class QHelpSearchEngine;

    QHelpSearchQueryWidget *queryWidget;
    QHelpSearchResultWidget *resultWidget;

    QHelpSearchIndexReader *indexReader;
    QHelpSearchIndexWriter *indexWriter;

    QPointer<QHelpEngineCore> helpEngine;
    QList<QHelpSearchEngine::SearchHit> hitList;

    QList<QHelpSearchQuery> m_queryList;
};

#include "qhelpsearchengine.moc"

/*!
    \class QHelpSearchQuery
    \since 4.4
    \inmodule QtHelp
    \brief The QHelpSearchQuery class contains the field name and the associated
    search term

    The QHelpSearchQuery class contains the field name and the associated search
    term. Depending on the field the search term might get split up into seperate
    terms to be parsed differently by the search engine.

    \sa QHelpSearchQueryWidget
*/

/*!
    \fn QHelpSearchQuery::QHelpSearchQuery()

    Constructs a new empty QHelpSearchQuery.
*/

/*!
    \fn QHelpSearchQuery::QHelpSearchQuery(FieldName field, const QStringList &wordList)

    Constructs a new QHelpSearchQuery and initializes it with the given \a field and \a wordList.
*/

/*!
    \enum QHelpSearchQuery::FieldName
    This enum type specifies the field names that are handled by the search engine.

    \value DEFAULT  the default field provided by the search widget, several terms should be
                    split and stored in the word list except search terms enclosed in quotes.
    \value FUZZY    a field only provided in use with clucene. Terms should be split in seperate
                    words and passed to the search engine.
    \value WITHOUT  a field only provided in use with clucene. Terms should be split in seperate
                    words and passed to the search engine.
    \value PHRASE   a field only provided in use with clucene. Terms should not be split in seperate
                    words.
    \value ALL      a field only provided in use with clucene. Terms should be split in seperate
                    words and passed to the search engine
    \value ATLEAST  a field only provided in use with clucene. Terms should be split in seperate
                    words and passed to the search engine
*/

/*!
    \class QHelpSearchEngine
    \since 4.4
    \inmodule QtHelp
    \brief The QHelpSearchEngine class provides access to widgets reusable
    to integrate fulltext search as well as to index and search documentation.

    Before the search engine can be used, one has to instantiate at least a
    QHelpEngineCore object that needs to be passed to the search engines constructor.
    This is required as the search engine needs to be connected to the help
    engines setupFinished() signal to know when it can start to index documentation.

    After starting the indexing process the signal indexingStarted() is emitted and
    on the end of the indexing process the indexingFinished() is emited. To stop
    the indexing one can call cancelIndexing().

    While the indexing process has finished, the search engine can now be used to search
    thru its index for a given term. To do this one may use the possibility of creating the
    QHelpSearchQuery list by self or reuse the QHelpSearchQueryWidget which has the inbuild
    functionality to set up a proper search querys list that get's passed to the search engines
    search() function.

    After the list of querys has been passed to the search engine, the signal searchingStarted()
    is emited and after the search has finished the searchingFinished() signal is emited. The
    search process can be stopped by calling cancelSearching().

    If the search succeeds, the searchingFinished() will be called with the search hits count,
    which can be reused to fetch the search hits from the search engine. Calling the hits()
    function with the range of hits you would like to get will return a list of the requested
    SearchHits. They basically constist at the moment of a pair of strings where the values
    of that pair are the documentation file path and the page title.

    To display the given hits use the QHelpSearchResultWidget or build up your own one if you need
    more advanced functionality. Note that the QHelpSearchResultWidget can not be instantiated
    directly, you must retrieve the widget from the search engine in use as all connections will be
    established for you by the widget itself.
*/

/*!
    \fn void QHelpSearchEngine::indexingStarted()

    This signal is emitted when indexing process is started.
*/

/*!
    \fn void QHelpSearchEngine::indexingFinished()

    This signal is emitted when the indexing process is complete.
*/

/*!
    \fn void QHelpSearchEngine::searchingStarted()

    This signal is emitted when the search process is started.
*/

/*!
    \fn void QHelpSearchEngine::searchingFinished(int hits)

    This signal is emitted when the search process is complete.
    The hit count is stored in \a hits.
*/

/*!
    Constructs a new search engine with the given \a parent. The search engine
    uses the given \a helpEngine to access the documentation that needs to be indexed.
    The QHelpEngine's setupFinished() signal is automatically connected to the
    QHelpSearchEngine's indexing function, so that new documentation will be indexed
    after the signal is emited.
*/
QHelpSearchEngine::QHelpSearchEngine(QHelpEngineCore *helpEngine, QObject *parent)
    : QObject(parent)
{
    d = new QHelpSearchEnginePrivate(helpEngine);

    connect(helpEngine, SIGNAL(setupFinished()), this, SLOT(indexDocumentation()));

    connect(d, SIGNAL(indexingStarted()), this, SIGNAL(indexingStarted()));
    connect(d, SIGNAL(indexingFinished()), this, SIGNAL(indexingFinished()));
    connect(d, SIGNAL(searchingStarted()), this, SIGNAL(searchingStarted()));
    connect(d, SIGNAL(searchingFinished(int)), this, SIGNAL(searchingFinished(int)));
}

/*!
    Destructs the search engine.
*/
QHelpSearchEngine::~QHelpSearchEngine()
{
    delete d;
}

/*!
    Returns a widget to use as input widget. Depending on your search engine
    configuration you will get a different widget with more or less subwidgets.
*/
QHelpSearchQueryWidget* QHelpSearchEngine::queryWidget()
{
    if (!d->queryWidget)
        d->queryWidget = new QHelpSearchQueryWidget();

    return d->queryWidget;
}

/*!
    Returns a widget that can hold and display the search results.
*/
QHelpSearchResultWidget* QHelpSearchEngine::resultWidget()
{
    if (!d->resultWidget)
        d->resultWidget = new QHelpSearchResultWidget(this);

    return d->resultWidget;
}

/*!
    Returns the amount of hits the search engine found.
*/
int QHelpSearchEngine::hitsCount() const
{
    return d->hitsCount();
}

/*!
    \typedef QHelpSearchEngine::SearchHit

    Typedef for QPair<QString, QString>.
    The values of that pair are the documentation file path and the page title.

    \sa hits()
*/

/*!
    Returns a list of search hits within the range of \a start \a end.
*/
QList<QHelpSearchEngine::SearchHit> QHelpSearchEngine::hits(int start, int end) const
{
   return d->hits(start, end);
}

/*!
    Returns the list of queries last searched for.
    \since 4.5
*/
QList<QHelpSearchQuery> QHelpSearchEngine::query() const
{
    return d->m_queryList;
}

/*!
    Forces the search engine to reindex all documentation files.
*/
void QHelpSearchEngine::reindexDocumentation()
{
    d->updateIndex(true);
}

/*!
    Stops the indexing process.
*/
void QHelpSearchEngine::cancelIndexing()
{
    d->cancelIndexing();
}

/*!
    Stops the search process.
*/
void QHelpSearchEngine::cancelSearching()
{
    d->cancelSearching();
}

/*!
    Starts the search process using the given list of querys \a queryList
    build by the search field name and the values to search for.
*/
void QHelpSearchEngine::search(const QList<QHelpSearchQuery> &queryList)
{
    d->search(queryList);
}

void QHelpSearchEngine::indexDocumentation()
{
    d->updateIndex();
}

QT_END_NAMESPACE
<|endoftext|>


<commit_before>//
//  Application.cpp
//  OpenGL Skeleton
//
//  Created by Paul Tolstoi on 28/07/15.
//
//

#include "Application.h"

#include <vector>

namespace lornar {

    Application::Application(const string &name)
    : m_name(name)
    , m_window(nullptr) {

        if(glfwInit() == GL_FALSE) {
            throw runtime_error("Could not initialize GLFW");
        }

        vector<const int> hint {
            GLFW_CONTEXT_VERSION_MAJOR, 3,
            GLFW_CONTEXT_VERSION_MINOR, 2,
            GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE,
            GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE,
            GLFW_DEPTH_BITS, 16, //no z-buffer required for system framebuffer
            GLFW_SAMPLES, 4, //Multisample anti aliasing samples
            GLFW_REFRESH_RATE, 60,
        };

        for (size_t h = 0; h < hint.size(); h += 2)
            glfwWindowHint(hint[h], hint[h+1]);

        m_window = glfwCreateWindow(640, 480, m_name.c_str(), nullptr, nullptr);

        if (!m_window) {
            throw runtime_error("OpenGL initialization failed, invalid window hints");
        }

        glfwMakeContextCurrent(m_window);

    }

    Application::~Application() {

        glfwTerminate();

    }

    void Application::run() {

        while (!glfwWindowShouldClose(m_window)) {
            glfwSwapBuffers(m_window);// Swap front and back buffers
            glfwPollEvents();       // Poll for and process events
        }

    }

}<commit_msg>fixed compiling error on windows when using const inside vector<commit_after>//
//  Application.cpp
//  OpenGL Skeleton
//
//  Created by Paul Tolstoi on 28/07/15.
//
//

#include "Application.h"

#include <vector>

namespace lornar {

    Application::Application(const string &name)
    : m_name(name)
    , m_window(nullptr) {

        if(glfwInit() == GL_FALSE) {
            throw runtime_error("Could not initialize GLFW");
        }

        vector<int> hint {
            GLFW_CONTEXT_VERSION_MAJOR, 3,
            GLFW_CONTEXT_VERSION_MINOR, 2,
            GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE,
            GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE,
            GLFW_DEPTH_BITS, 16, //no z-buffer required for system framebuffer
            GLFW_SAMPLES, 4, //Multisample anti aliasing samples
            GLFW_REFRESH_RATE, 60,
        };

        for (size_t h = 0; h < hint.size(); h += 2)
            glfwWindowHint(hint[h], hint[h+1]);

        m_window = glfwCreateWindow(640, 480, m_name.c_str(), nullptr, nullptr);

        if (!m_window) {
            throw runtime_error("OpenGL initialization failed, invalid window hints");
        }

        glfwMakeContextCurrent(m_window);

    }

    Application::~Application() {

        glfwTerminate();

    }

    void Application::run() {

        while (!glfwWindowShouldClose(m_window)) {
            glfwSwapBuffers(m_window);// Swap front and back buffers
            glfwPollEvents();       // Poll for and process events
        }

    }

}<|endoftext|>