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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTubeSpatialObjectTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

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

/*
* itkTubeSpatialObject test file.
* This test file test also the basic functions of the CompositeSpatialObject class,
* like Add/RemoveSpatialObject(...), Get/SetChildren(...), etc...
*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkPoint.h"
#include "itkVector.h"
#include "itkAffineTransform.h"
#include "itkTubeSpatialObjectPoint.h"
#include "itkTubeSpatialObject.h"
#include "itkGroupSpatialObject.h"
#include "itkExceptionObject.h"

#include <vnl/vnl_math.h>

int itkTubeSpatialObjectTest(int, char **)
{
  typedef double                                      ScalarType;
  typedef bool                                        OutputType;
  typedef itk::Vector< ScalarType, 3>                 Vector;
  typedef itk::Vector< OutputType, 3>                 OutputVector;
  typedef itk::Point< ScalarType, 3>                  Point;
  typedef itk::Matrix< ScalarType, 3, 3>              Matrix;
  typedef itk::TubeSpatialObject<3>                   TubeType;
  typedef itk::SmartPointer< TubeType >               TubePointer;
  typedef itk::GroupSpatialObject<3>                  GroupType;
  typedef itk::SmartPointer< GroupType >              GroupPointer;
  typedef TubeType::TubePointType                     TubePointType;
  typedef TubeType::PointListType                     TubePointListType;
  typedef std::list< itk::SpatialObject<3> * >        ChildrenListType;
  typedef ChildrenListType *                          ChildrenListPointer;

  Vector axis, translation;
  Point in, out;
  double angle;
  bool passed = true;

  //======================================
  // testing of a single SpatialObject...
  //======================================

  std::cout<<"=================================="<<std::endl;
  std::cout<<"Testing SpatialObject:"<<std::endl<<std::endl;

  TubePointer tube1 = TubeType::New();
  TubePointListType list;

  TubeType::TransformType::OffsetType offset;
  offset.Fill(10);
  tube1->GetTransform()->SetOffset(offset);
  tube1->ComputeGlobalTransform();

  for( unsigned int i=0; i<10; i++)
    {
    TubePointType p;
    p.SetPosition(i,i,i);
    p.SetRadius(1);
    list.push_back(p);
    }

  tube1->GetProperty()->SetName("Tube 1");
  tube1->SetId(1);
  tube1->SetPoints(list);
  tube1->ComputeBoundingBox();

  in.Fill(15);
  out.Fill(5);

  std::cout<<"IsInside()...";
  if( !tube1->IsInside(in) || tube1->IsInside(out) )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  TubeType::OutputVectorType derivative;

  std::cout<<"DerivativeAt()...";
  try
    {
    tube1->DerivativeAt(in,1,derivative);
    }
  catch(...)
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }

  TubeType::OutputVectorType expectedDerivative;
  expectedDerivative.Fill(0);

  if( expectedDerivative != derivative )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout<<"itkTubeSpatialObjectTest ";
  if( passed )
    {
    std::cout<<"[PASSED]"<<std::endl;
    }
  else
    {
    std::cout<<"[FAILED]"<<std::endl;
    }

  //==============================================
  // testing of a single CompositeSpatialObject...
  //==============================================

  std::cout<<"=================================="<<std::endl;
  std::cout<<"Testing GroupSpatialObject:"<<std::endl<<std::endl;

  ChildrenListType childrenList;
  ChildrenListPointer returnedList;
  unsigned int nbChildren;

  TubePointer tube2 = TubeType::New();
  tube2->GetProperty()->SetName("Tube 2");
  tube2->SetId(2);
  tube2->SetPoints(list);
  tube2->ComputeBoundingBox();

  TubePointer tube3 = TubeType::New();
  tube3->GetProperty()->SetName("Tube 3");
  tube3->SetId(3);
  tube3->SetPoints(list);
  tube3->ComputeBoundingBox();

  GroupPointer tubeNet1 = GroupType::New();
  tubeNet1->GetProperty()->SetName("tube network 1");

  tubeNet1->AddSpatialObject( tube1 );
  tubeNet1->AddSpatialObject( tube2 );
  tubeNet1->AddSpatialObject( tube3 );

  // testing the AddSpatialObject() function...
  nbChildren = tubeNet1->GetNumberOfChildren();

  std::cout<<"AddSpatialObject()...";
  if( nbChildren != 3 )
    {
    std::cout<<"[FAILED] ["<< nbChildren << "!= 3]" << std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  // testing the RemoveSpatialObject() function...
  tubeNet1->RemoveSpatialObject( tube1 );
  tubeNet1->RemoveSpatialObject( tube2 );
  tubeNet1->RemoveSpatialObject( tube3 );

  nbChildren = tubeNet1->GetNumberOfChildren();

  std::cout<<"RemoveSpatialObject()...";
  if( nbChildren != 0 )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->AddSpatialObject( tube1 );
  tubeNet1->AddSpatialObject( tube2 );
  tubeNet1->AddSpatialObject( tube3 );

  // testing the GetChildren() function...
  childrenList.push_back( tube1.GetPointer() );
  childrenList.push_back( tube2.GetPointer() );
  childrenList.push_back( tube3.GetPointer() );

  returnedList = tubeNet1->GetChildren();

  if( childrenList.size() == returnedList->size() )
    {
    ChildrenListType::iterator itTest = returnedList->begin();
    ChildrenListType::iterator it = childrenList.begin();
    ChildrenListType::iterator end = childrenList.end();

    for(unsigned int i=0; it!=end; itTest++,it++,i++ )
      {
      if((*itTest) != (*it))
        {
        passed = false;
        break;
        }
      }

    }
  else
    {
    passed = false;
    }

  std::cout<<"GetChildren()...";
  if( !passed )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->RemoveSpatialObject( tube1 );
  tubeNet1->RemoveSpatialObject( tube2 );
  tubeNet1->RemoveSpatialObject( tube3 );

  // testing the SetChildren() function...
  tubeNet1->SetChildren(childrenList);
  returnedList = tubeNet1->GetChildren();

  if( childrenList.size() == returnedList->size() )
    {
    ChildrenListType::iterator itTest = returnedList->begin();
    ChildrenListType::iterator it = childrenList.begin();
    ChildrenListType::iterator end = childrenList.end();

    passed = true;

    for(unsigned int i=0; it!=end; itTest++,it++,i++ )
      {
      if((*itTest) != (*it))
        {
        passed = false;
        break;
        }
      }
    }
  else
    {
    passed = false;
    }

  std::cout<<"SetChildren()...";
  if( !passed )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->ComputeBoundingBox();

  std::cout<<"HasParent()...";
  if( !tube1->HasParent() )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  translation.Fill(10);
  tubeNet1->GetTransform()->Translate(translation,false);
  tubeNet1->ComputeGlobalTransform();

  axis.Fill(0);
  axis[1] = 1;

  angle = vnl_math::pi_over_2;
  tube2->GetTransform()->Rotate3D(axis,angle);
  tube2->ComputeGlobalTransform();

  angle = -vnl_math::pi_over_2;
  tube3->GetTransform()->Rotate3D(axis,angle);
  tube3->ComputeGlobalTransform();

  in.Fill(25);
  out.Fill(15);

  Point p1,p2;
  p1.Fill(15);
  p1[2]=5;
  p2.Fill(15);
  p2[0]=5;

  std::cout<<"IsInside()...";
  if( !tubeNet1->IsInside(in, true) || tubeNet1->IsInside(out, true) )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout<<"DerivativeAt()...";
  try
    {
    tubeNet1->DerivativeAt(in,(unsigned short)1,derivative,true);
    }
  catch(...)
    {
    std::cout<<"[FAILED]"<<std::endl;
    }

  if( derivative == expectedDerivative )
    {
    std::cout<<"[PASSED]"<<std::endl;
    }
  else
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }

  //====================================================
  // testing of references behavior for SpatialObject...
  //====================================================

  std::cout<<"=============================================="<<std::endl;
  std::cout<<"Testing references behavior for SpatialObject:"<<std::endl<<std::endl;

  TubePointer tube = TubeType::New();
  GroupPointer net = GroupType::New();

  unsigned int tubeCount, netCount;
  tubeCount = tube->GetReferenceCount();
  netCount = net->GetReferenceCount();

  std::cout<<"References test...";
  if( tubeCount != 1 )
    {
    std::cout<<"[FAILED]: Problem in Tube initialization of references count"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    TubePointer localTube = tube;
    tubeCount = tube->GetReferenceCount();
    if( tubeCount != 2 )
      {
      std::cout<<"[FAILED]: Problem in Tube with incrementation of references count"<<std::endl;
      return EXIT_FAILURE;
      }
    }

  if( netCount != 1 )
    {
    std::cout<<"[FAILED]: Problem in TubeNetwork initialization of references count"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    GroupPointer localNet = net;
    netCount = net->GetReferenceCount();
    if( netCount != 2 )
      {
      std::cout<<"[FAILED]: Problem in TubeNetwork with incrementation of references count"<<std::endl;
      return EXIT_FAILURE;
      }
    }

  tubeCount = tube->GetReferenceCount();
  netCount = net->GetReferenceCount();

  if( tubeCount != 1 )
    {
      std::cout<<"[FAILED]: Problem in Tube with decrementation of references count"<<std::endl;
      return EXIT_FAILURE;
    }

  if( netCount != 1 )
    {
      std::cout<<"[FAILED]: Problem in TubeNetwork with decrementation of references count"<<std::endl;
      return EXIT_FAILURE;
    }

  std::cout<<"[PASSED]"<<std::endl;

  return EXIT_SUCCESS;

}
<commit_msg>FIX: deleted pointers to list<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTubeSpatialObjectTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2002 Insight Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

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

/*
* itkTubeSpatialObject test file.
* This test file test also the basic functions of the CompositeSpatialObject class,
* like Add/RemoveSpatialObject(...), Get/SetChildren(...), etc...
*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include "itkPoint.h"
#include "itkVector.h"
#include "itkAffineTransform.h"
#include "itkTubeSpatialObjectPoint.h"
#include "itkTubeSpatialObject.h"
#include "itkGroupSpatialObject.h"
#include "itkExceptionObject.h"

#include <vnl/vnl_math.h>

int itkTubeSpatialObjectTest(int, char **)
{
  typedef double                                      ScalarType;
  typedef bool                                        OutputType;
  typedef itk::Vector< ScalarType, 3>                 Vector;
  typedef itk::Vector< OutputType, 3>                 OutputVector;
  typedef itk::Point< ScalarType, 3>                  Point;
  typedef itk::Matrix< ScalarType, 3, 3>              Matrix;
  typedef itk::TubeSpatialObject<3>                   TubeType;
  typedef itk::SmartPointer< TubeType >               TubePointer;
  typedef itk::GroupSpatialObject<3>                  GroupType;
  typedef itk::SmartPointer< GroupType >              GroupPointer;
  typedef TubeType::TubePointType                     TubePointType;
  typedef TubeType::PointListType                     TubePointListType;
  typedef std::list< itk::SpatialObject<3> * >        ChildrenListType;
  typedef ChildrenListType *                          ChildrenListPointer;

  Vector axis, translation;
  Point in, out;
  double angle;
  bool passed = true;

  //======================================
  // testing of a single SpatialObject...
  //======================================

  std::cout<<"=================================="<<std::endl;
  std::cout<<"Testing SpatialObject:"<<std::endl<<std::endl;

  TubePointer tube1 = TubeType::New();
  TubePointListType list;

  TubeType::TransformType::OffsetType offset;
  offset.Fill(10);
  tube1->GetTransform()->SetOffset(offset);
  tube1->ComputeGlobalTransform();

  for( unsigned int i=0; i<10; i++)
    {
    TubePointType p;
    p.SetPosition(i,i,i);
    p.SetRadius(1);
    list.push_back(p);
    }

  tube1->GetProperty()->SetName("Tube 1");
  tube1->SetId(1);
  tube1->SetPoints(list);
  tube1->ComputeBoundingBox();

  in.Fill(15);
  out.Fill(5);

  std::cout<<"IsInside()...";
  if( !tube1->IsInside(in) || tube1->IsInside(out) )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  TubeType::OutputVectorType derivative;

  std::cout<<"DerivativeAt()...";
  try
    {
    tube1->DerivativeAt(in,1,derivative);
    }
  catch(...)
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }

  TubeType::OutputVectorType expectedDerivative;
  expectedDerivative.Fill(0);

  if( expectedDerivative != derivative )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout<<"itkTubeSpatialObjectTest ";
  if( passed )
    {
    std::cout<<"[PASSED]"<<std::endl;
    }
  else
    {
    std::cout<<"[FAILED]"<<std::endl;
    }

  //==============================================
  // testing of a single CompositeSpatialObject...
  //==============================================

  std::cout<<"=================================="<<std::endl;
  std::cout<<"Testing GroupSpatialObject:"<<std::endl<<std::endl;

  ChildrenListType childrenList;
  ChildrenListPointer returnedList;
  unsigned int nbChildren;

  TubePointer tube2 = TubeType::New();
  tube2->GetProperty()->SetName("Tube 2");
  tube2->SetId(2);
  tube2->SetPoints(list);
  tube2->ComputeBoundingBox();

  TubePointer tube3 = TubeType::New();
  tube3->GetProperty()->SetName("Tube 3");
  tube3->SetId(3);
  tube3->SetPoints(list);
  tube3->ComputeBoundingBox();

  GroupPointer tubeNet1 = GroupType::New();
  tubeNet1->GetProperty()->SetName("tube network 1");

  tubeNet1->AddSpatialObject( tube1 );
  tubeNet1->AddSpatialObject( tube2 );
  tubeNet1->AddSpatialObject( tube3 );

  // testing the AddSpatialObject() function...
  nbChildren = tubeNet1->GetNumberOfChildren();

  std::cout<<"AddSpatialObject()...";
  if( nbChildren != 3 )
    {
    std::cout<<"[FAILED] ["<< nbChildren << "!= 3]" << std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  // testing the RemoveSpatialObject() function...
  tubeNet1->RemoveSpatialObject( tube1 );
  tubeNet1->RemoveSpatialObject( tube2 );
  tubeNet1->RemoveSpatialObject( tube3 );

  nbChildren = tubeNet1->GetNumberOfChildren();

  std::cout<<"RemoveSpatialObject()...";
  if( nbChildren != 0 )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->AddSpatialObject( tube1 );
  tubeNet1->AddSpatialObject( tube2 );
  tubeNet1->AddSpatialObject( tube3 );

  // testing the GetChildren() function...
  childrenList.push_back( tube1.GetPointer() );
  childrenList.push_back( tube2.GetPointer() );
  childrenList.push_back( tube3.GetPointer() );

  returnedList = tubeNet1->GetChildren();

  if( childrenList.size() == returnedList->size() )
    {
    ChildrenListType::iterator itTest = returnedList->begin();
    ChildrenListType::iterator it = childrenList.begin();
    ChildrenListType::iterator end = childrenList.end();

    for(unsigned int i=0; it!=end; itTest++,it++,i++ )
      {
      if((*itTest) != (*it))
        {
        passed = false;
        break;
        }
      }

    }
  else
    {
    passed = false;
    }

  std::cout<<"GetChildren()...";
  if( !passed )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->RemoveSpatialObject( tube1 );
  tubeNet1->RemoveSpatialObject( tube2 );
  tubeNet1->RemoveSpatialObject( tube3 );

  delete returnedList;

  // testing the SetChildren() function...
  tubeNet1->SetChildren(childrenList);
  returnedList = tubeNet1->GetChildren();

  if( childrenList.size() == returnedList->size() )
    {
    ChildrenListType::iterator itTest = returnedList->begin();
    ChildrenListType::iterator it = childrenList.begin();
    ChildrenListType::iterator end = childrenList.end();

    passed = true;

    for(unsigned int i=0; it!=end; itTest++,it++,i++ )
      {
      if((*itTest) != (*it))
        {
        passed = false;
        break;
        }
      }
    }
  else
    {
    passed = false;
    }

  delete returnedList;
  std::cout<<"SetChildren()...";
  if( !passed )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  tubeNet1->ComputeBoundingBox();

  std::cout<<"HasParent()...";
  if( !tube1->HasParent() )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  translation.Fill(10);
  tubeNet1->GetTransform()->Translate(translation,false);
  tubeNet1->ComputeGlobalTransform();

  axis.Fill(0);
  axis[1] = 1;

  angle = vnl_math::pi_over_2;
  tube2->GetTransform()->Rotate3D(axis,angle);
  tube2->ComputeGlobalTransform();

  angle = -vnl_math::pi_over_2;
  tube3->GetTransform()->Rotate3D(axis,angle);
  tube3->ComputeGlobalTransform();

  in.Fill(25);
  out.Fill(15);

  Point p1,p2;
  p1.Fill(15);
  p1[2]=5;
  p2.Fill(15);
  p2[0]=5;

  std::cout<<"IsInside()...";
  if( !tubeNet1->IsInside(in, true) || tubeNet1->IsInside(out, true) )
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    std::cout<<"[PASSED]"<<std::endl;
    }

  std::cout<<"DerivativeAt()...";
  try
    {
    tubeNet1->DerivativeAt(in,(unsigned short)1,derivative,true);
    }
  catch(...)
    {
    std::cout<<"[FAILED]"<<std::endl;
    }

  if( derivative == expectedDerivative )
    {
    std::cout<<"[PASSED]"<<std::endl;
    }
  else
    {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
    }

  //====================================================
  // testing of references behavior for SpatialObject...
  //====================================================

  std::cout<<"=============================================="<<std::endl;
  std::cout<<"Testing references behavior for SpatialObject:"<<std::endl<<std::endl;

  TubePointer tube = TubeType::New();
  GroupPointer net = GroupType::New();

  unsigned int tubeCount, netCount;
  tubeCount = tube->GetReferenceCount();
  netCount = net->GetReferenceCount();

  std::cout<<"References test...";
  if( tubeCount != 1 )
    {
    std::cout<<"[FAILED]: Problem in Tube initialization of references count"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    TubePointer localTube = tube;
    tubeCount = tube->GetReferenceCount();
    if( tubeCount != 2 )
      {
      std::cout<<"[FAILED]: Problem in Tube with incrementation of references count"<<std::endl;
      return EXIT_FAILURE;
      }
    }

  if( netCount != 1 )
    {
    std::cout<<"[FAILED]: Problem in TubeNetwork initialization of references count"<<std::endl;
    return EXIT_FAILURE;
    }
  else
    {
    GroupPointer localNet = net;
    netCount = net->GetReferenceCount();
    if( netCount != 2 )
      {
      std::cout<<"[FAILED]: Problem in TubeNetwork with incrementation of references count"<<std::endl;
      return EXIT_FAILURE;
      }
    }

  tubeCount = tube->GetReferenceCount();
  netCount = net->GetReferenceCount();

  if( tubeCount != 1 )
    {
      std::cout<<"[FAILED]: Problem in Tube with decrementation of references count"<<std::endl;
      return EXIT_FAILURE;
    }

  if( netCount != 1 )
    {
      std::cout<<"[FAILED]: Problem in TubeNetwork with decrementation of references count"<<std::endl;
      return EXIT_FAILURE;
    }

  std::cout<<"[PASSED]"<<std::endl;

  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>#include "glwidget.h"

#include <time.h>
#include <math.h>

#include <QKeyEvent>
#include <QTimer>
#include <QVector3D>
#include <QGLShader>
#include <QGLShaderProgram>

#include "color.h"
#include "emitter.h"

#include "renderers/rend_point.h"
#include "renderers/rend_sphere.h"
#include "renderers/rend_square.h"

#include "initializers/init_color.h"
#include "initializers/init_directioncone.h"
#include "initializers/init_lifetime.h"
#include "initializers/init_radius.h"
#include "initializers/init_speed.h"
#include "initializers/init_speedoffset.h"
#include "initializers/init_positionoffset.h"
#include "initializers/init_positionring.h"

#include "operators/oper_acceleration.h"
#include "operators/oper_decay.h"
#include "operators/oper_drag.h"
#include "operators/oper_fade.h"

GLWidget::GLWidget(QWidget *parent) :
  QGLWidget(parent),
  _camera(),
  _timer(),
  _qtimer(NULL),
  _vertShader(NULL),
  _fragShader(NULL),
  _shaderProgram(NULL),
  _emitter(NULL) {
  // Set the animation timer
  _qtimer = new QTimer(this);
  connect(_qtimer, SIGNAL(timeout()), this, SLOT(animate()));
  _qtimer->start();

  // Fire the internal timer
  _timer.start();
}

GLWidget::~GLWidget() {
  if(_qtimer) delete _qtimer;
  if(_emitter) delete _emitter;
}

QSize GLWidget::minimumSizeHint() const {
  return QSize(80, 60);
}

QSize GLWidget::sizeHint() const {
  return QSize(600, 600);
}

void GLWidget::animate() {
  _timer.update();

  _emitter->update(_timer.elapsed());

  updateGL();
}

void GLWidget::initializeGL() {
  srand(time(NULL));

  glClearColor(.0, .0, .0, 1.0);
  glShadeModel(GL_FLAT);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);

  glEnable( GL_BLEND );
  glBlendFunc( GL_SRC_ALPHA, GL_ONE );

  // Eye candy? :3
  glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  glHint( GL_POINT_SMOOTH_HINT, GL_NICEST );

  initShaders();

  _camera.rotate(30, -20);

  /* water */
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.0001 );

  _emitter->renderer(new Rend_Square());

  _emitter->addInitializer(new Init_Lifetime(4, 2));
  _emitter->addInitializer(new Init_Color(Color(90, 100, 140, 0.1), Color(120, 140, 180, 0.8)));
  _emitter->addInitializer(new Init_Speed(0.8, 0.8));
  _emitter->addInitializer(new Init_Radius(0.01, 0.001));
  _emitter->addInitializer(new Init_PositionRing(Vector3D(0, 0, 0), Vector3D(0, 0, 1), 0.05, 0));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, 0.8, 0), 25, 10));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Acceleration(Vector3D(0, -0.4, 0)));
  _emitter->addOperator(new Oper_Drag(0.1));
  _emitter->addOperator(new Oper_Fade(0.5));
  /* /water */

  /* fire */ /*
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.0001 );

  _emitter->renderer(new Rend_Square());

  _emitter->addInitializer(new Init_Lifetime(2, 1));
  _emitter->addInitializer(new Init_Color(Color(240, 10, 0), Color(140, 80, 20)));
  _emitter->addInitializer(new Init_Speed(0.1, 0.4));
  _emitter->addInitializer(new Init_Radius(0.01, 0.001));
  _emitter->addInitializer(new Init_PositionOffset(Vector3D(-.1, 0, -.1), Vector3D(.1, 0, .1)));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, 1, 0), 20));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Acceleration(Vector3D(0, 0.1, 0)));
  _emitter->addOperator(new Oper_Fade(1.0));
  /* /fire */

  /* ? */ /*
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.0002 );

  _emitter->renderer(new Rend_Point());

  _emitter->addInitializer(new Init_Lifetime(4, 2));
  _emitter->addInitializer(new Init_Color(Color(200, 10, 0), Color(140, 80, 20)));
  _emitter->addInitializer(new Init_Speed(0.8, 0.8));
  _emitter->addInitializer(new Init_Radius(2.0, 1.1));
  _emitter->addInitializer(new Init_PositionRing(Vector3D(0, 0, 0), Vector3D(0, 0, 1), 0.2, 0));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, -0.8, 0), 25, 10));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Acceleration(Vector3D(0, -0.001, 0)));
  _emitter->addOperator(new Oper_Drag(0.1));
  _emitter->addOperator(new Oper_Fade(0.5));
  /* /? */

  /* stars */ /*
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.05 );

  _emitter->renderer(new Rend_Square());

  _emitter->addInitializer(new Init_Lifetime(2, 1));
  _emitter->addInitializer(new Init_Color(Color(255, 255, 255), Color(255, 255, 255)));
  _emitter->addInitializer(new Init_Speed(0.01, 0.02));
  _emitter->addInitializer(new Init_Radius(0.001, 0.005));
  _emitter->addInitializer(new Init_PositionOffset(Vector3D(-1, -1, -1), Vector3D(1, 1, 1)));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, -0.8, 0), 25, 360));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Fade(0.5));
  /* /stars */

  /* ? */ /*
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.01 );

  //_emitter->renderer(new Rend_Point());
  _emitter->renderer(new Rend_Sphere(2));
  //_emitter->renderer(new Rend_Square());

  _emitter->addInitializer(new Init_Lifetime(4, 3));
  _emitter->addInitializer(new Init_Color(Color(200, 200, 255), Color(255, 255, 255)));
  _emitter->addInitializer(new Init_Speed(0, 0));
  _emitter->addInitializer(new Init_Radius(0.01, 0.001));
  _emitter->addInitializer(new Init_PositionRing(Vector3D(0, 0, 0), Vector3D(0, 0, 1), 1));
  _emitter->addInitializer(new Init_PositionOffset(Vector3D(0, 1, 0), Vector3D(0, 1, 0)));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, 1, 0), 360));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Acceleration(Vector3D(0, -0.2, 0)));
  _emitter->addOperator(new Oper_Fade(1.0));
  /* /? */
}

void GLWidget::paintGL() {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix();

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  _camera.apply();

  drawAxis();

  _emitter->draw();

  glPopMatrix();
}

void GLWidget::resizeGL(int w, int h) {
  glViewport(0, 0, w, h);

  glPushMatrix();
  glMatrixMode(GL_PROJECTION); //set the matrix to projection
  glLoadIdentity();
  perspective(75.0, (GLfloat)w / (GLfloat)h, -10.0, 200.0);
  glPopMatrix();
}

void GLWidget::keyPressEvent(QKeyEvent *event) {
  switch(event->key()){
    case Qt::Key_W:
    case Qt::Key_Up:
    break;
  }
}

void GLWidget::initShaders() {
  _vertShader = new QGLShader(QGLShader::Vertex);
  _fragShader = new QGLShader(QGLShader::Fragment);

  if(!_vertShader->compileSourceFile(":/vshader.glsl")) {
    qWarning() << _vertShader->log();
  }

  if(!_fragShader->compileSourceFile(":/fshader.glsl")) {
    qWarning() << _fragShader->log();
  }

  _shaderProgram = new QGLShaderProgram();
  _shaderProgram->addShader(_vertShader);
  _shaderProgram->addShader(_fragShader);

  if(!_shaderProgram->link()) {
    qWarning() << _shaderProgram->log();
  }
  else {
    _shaderProgram->bind();
  }
}

void GLWidget::showFPS() {
  qDebug() << "FPS: " << _timer.fps();
}

void GLWidget::drawAxis(float len) {
  glBegin(GL_LINES);
    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(len, 0.0, 0.0);
  glEnd();

  glBegin(GL_LINES);
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(0.0, len, 0.0);
  glEnd();

  glBegin(GL_LINES);
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(0.0, 0.0, len);
  glEnd();
}

void GLWidget::perspective(double fovY, double aspect, double zNear, double zFar) {
  double fW, fH;
  fH = tan(M_PI * fovY / 360) * zNear;
  fW = fH * aspect;
  glFrustum( -fW, fW, -fH, fH, zNear, zFar );
}<commit_msg>Changed sample code<commit_after>#include "glwidget.h"

#include <time.h>
#include <math.h>

#include <QKeyEvent>
#include <QTimer>
#include <QVector3D>
#include <QGLShader>
#include <QGLShaderProgram>

#include "color.h"
#include "emitter.h"

#include "renderers/rend_point.h"
#include "renderers/rend_sphere.h"
#include "renderers/rend_square.h"

#include "initializers/init_color.h"
#include "initializers/init_directioncone.h"
#include "initializers/init_lifetime.h"
#include "initializers/init_radius.h"
#include "initializers/init_speed.h"
#include "initializers/init_speedoffset.h"
#include "initializers/init_positionoffset.h"
#include "initializers/init_positionring.h"

#include "operators/oper_acceleration.h"
#include "operators/oper_decay.h"
#include "operators/oper_drag.h"
#include "operators/oper_fade.h"

GLWidget::GLWidget(QWidget *parent) :
  QGLWidget(parent),
  _camera(),
  _timer(),
  _qtimer(NULL),
  _vertShader(NULL),
  _fragShader(NULL),
  _shaderProgram(NULL),
  _emitter(NULL) {
  // Set the animation timer
  _qtimer = new QTimer(this);
  connect(_qtimer, SIGNAL(timeout()), this, SLOT(animate()));
  _qtimer->start();

  // Fire the internal timer
  _timer.start();
}

GLWidget::~GLWidget() {
  if(_qtimer) delete _qtimer;
  if(_emitter) delete _emitter;
}

QSize GLWidget::minimumSizeHint() const {
  return QSize(80, 60);
}

QSize GLWidget::sizeHint() const {
  return QSize(600, 600);
}

void GLWidget::animate() {
  _timer.update();

  _emitter->update(_timer.elapsed());

  updateGL();
}

void GLWidget::initializeGL() {
  srand(time(NULL));

  glClearColor(.0, .0, .0, 1.0);
  glShadeModel(GL_FLAT);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_CULL_FACE);

  glEnable( GL_BLEND );
  glBlendFunc( GL_SRC_ALPHA, GL_ONE );

  // Eye candy? :3
  glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  glHint( GL_POINT_SMOOTH_HINT, GL_NICEST );

  initShaders();

  _camera.rotate(30, -20);

  /* water */
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.0001 );

  _emitter->renderer(new Rend_Point());

  _emitter->addInitializer(new Init_Lifetime(4, 2));
  _emitter->addInitializer(new Init_Color(Color(40, 40, 100, 0.1), Color(80, 90, 120, 0.8)));
  _emitter->addInitializer(new Init_Speed(0.8, 0.8));
  _emitter->addInitializer(new Init_Radius(2.5, 1.5));
  _emitter->addInitializer(new Init_PositionRing(Vector3D(0, 0, 0), Vector3D(0, 0, 1), 0.05, 0));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, 0.8, 0), 25, 10));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Acceleration(Vector3D(0, -0.4, 0)));
  _emitter->addOperator(new Oper_Drag(0.1));
  _emitter->addOperator(new Oper_Fade(0.5));
  /* /water */

  /* fire */ /*
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.0001 );

  _emitter->renderer(new Rend_Square());

  _emitter->addInitializer(new Init_Lifetime(2, 1));
  _emitter->addInitializer(new Init_Color(Color(240, 10, 0), Color(140, 80, 20)));
  _emitter->addInitializer(new Init_Speed(0.1, 0.4));
  _emitter->addInitializer(new Init_Radius(0.01, 0.001));
  _emitter->addInitializer(new Init_PositionOffset(Vector3D(-.1, 0, -.1), Vector3D(.1, 0, .1)));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, 1, 0), 20));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Acceleration(Vector3D(0, 0.1, 0)));
  _emitter->addOperator(new Oper_Fade(1.0));
  /* /fire */

  /* ? */ /*
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.0002 );

  _emitter->renderer(new Rend_Point());

  _emitter->addInitializer(new Init_Lifetime(4, 2));
  _emitter->addInitializer(new Init_Color(Color(200, 10, 0), Color(140, 80, 20)));
  _emitter->addInitializer(new Init_Speed(0.8, 0.8));
  _emitter->addInitializer(new Init_Radius(2.0, 1.1));
  _emitter->addInitializer(new Init_PositionRing(Vector3D(0, 0, 0), Vector3D(0, 0, 1), 0.2, 0));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, -0.8, 0), 25, 10));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Acceleration(Vector3D(0, -0.001, 0)));
  _emitter->addOperator(new Oper_Drag(0.1));
  _emitter->addOperator(new Oper_Fade(0.5));
  /* /? */

  /* stars */ /*
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.05 );

  _emitter->renderer(new Rend_Square());

  _emitter->addInitializer(new Init_Lifetime(2, 1));
  _emitter->addInitializer(new Init_Color(Color(255, 255, 255), Color(255, 255, 255)));
  _emitter->addInitializer(new Init_Speed(0.01, 0.02));
  _emitter->addInitializer(new Init_Radius(0.001, 0.005));
  _emitter->addInitializer(new Init_PositionOffset(Vector3D(-1, -1, -1), Vector3D(1, 1, 1)));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, -0.8, 0), 25, 360));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Fade(0.5));
  /* /stars */

  /* ? */ /*
  _emitter = new Emitter(Vector3D(0, 0, 0), 0.01 );

  //_emitter->renderer(new Rend_Point());
  _emitter->renderer(new Rend_Sphere(2));
  //_emitter->renderer(new Rend_Square());

  _emitter->addInitializer(new Init_Lifetime(4, 3));
  _emitter->addInitializer(new Init_Color(Color(200, 200, 255), Color(255, 255, 255)));
  _emitter->addInitializer(new Init_Speed(0, 0));
  _emitter->addInitializer(new Init_Radius(0.01, 0.001));
  _emitter->addInitializer(new Init_PositionRing(Vector3D(0, 0, 0), Vector3D(0, 0, 1), 1));
  _emitter->addInitializer(new Init_PositionOffset(Vector3D(0, 1, 0), Vector3D(0, 1, 0)));
  _emitter->addInitializer(new Init_DirectionCone(Vector3D(0, 1, 0), 360));

  _emitter->addOperator(new Oper_Decay());
  _emitter->addOperator(new Oper_Acceleration(Vector3D(0, -0.2, 0)));
  _emitter->addOperator(new Oper_Fade(1.0));
  /* /? */
}

void GLWidget::paintGL() {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix();

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  _camera.apply();

  drawAxis();

  _emitter->draw();

  glPopMatrix();
}

void GLWidget::resizeGL(int w, int h) {
  glViewport(0, 0, w, h);

  glPushMatrix();
  glMatrixMode(GL_PROJECTION); //set the matrix to projection
  glLoadIdentity();
  perspective(75.0, (GLfloat)w / (GLfloat)h, -10.0, 200.0);
  glPopMatrix();
}

void GLWidget::keyPressEvent(QKeyEvent *event) {
  switch(event->key()){
    case Qt::Key_W:
    case Qt::Key_Up:
    break;
  }
}

void GLWidget::initShaders() {
  _vertShader = new QGLShader(QGLShader::Vertex);
  _fragShader = new QGLShader(QGLShader::Fragment);

  if(!_vertShader->compileSourceFile(":/vshader.glsl")) {
    qWarning() << _vertShader->log();
  }

  if(!_fragShader->compileSourceFile(":/fshader.glsl")) {
    qWarning() << _fragShader->log();
  }

  _shaderProgram = new QGLShaderProgram();
  _shaderProgram->addShader(_vertShader);
  _shaderProgram->addShader(_fragShader);

  if(!_shaderProgram->link()) {
    qWarning() << _shaderProgram->log();
  }
  else {
    _shaderProgram->bind();
  }
}

void GLWidget::showFPS() {
  qDebug() << "FPS: " << _timer.fps();
}

void GLWidget::drawAxis(float len) {
  glBegin(GL_LINES);
    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(len, 0.0, 0.0);
  glEnd();

  glBegin(GL_LINES);
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(0.0, len, 0.0);
  glEnd();

  glBegin(GL_LINES);
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(0.0, 0.0, len);
  glEnd();
}

void GLWidget::perspective(double fovY, double aspect, double zNear, double zFar) {
  double fW, fH;
  fH = tan(M_PI * fovY / 360) * zNear;
  fW = fH * aspect;
  glFrustum( -fW, fW, -fH, fH, zNear, zFar );
}<|endoftext|>


<commit_before>/*
 * checked_test.cpp
 */
#include <chrono>
#include <system_error>
#include "gtest/gtest.h"
#include "checked_mutex.hpp"
#include "checked_shared_mutex.hpp"
#include "yamc_testutil.hpp"

#if YAMC_CHECKED_CALL_ABORT
// call std::abort() on check failure
#if TEST_PLATFORM_WINDOWS
//
// NOTE:
//   Some death tests (*.AbandonMutexSide) does not work correctly on Windows platform.
//
#define EXPECT_CHECK_FAILURE(statement_) EXPECT_EXIT(statement_, ::testing::ExitedWithCode(3), "")
#else
#define EXPECT_CHECK_FAILURE(statement_) EXPECT_EXIT(statement_, ::testing::KilledBySignal(SIGABRT), "")
#endif
#define EXPECT_CHECK_FAILURE_OUTER(block_) EXPECT_CHECK_FAILURE(block_)
#define EXPECT_CHECK_FAILURE_INNER(block_) block_

#else
// throw an exception on check failure
#define EXPECT_CHECK_FAILURE(statement_) EXPECT_THROW(statement_, std::system_error)
#define EXPECT_CHECK_FAILURE_OUTER(block_) block_
#define EXPECT_CHECK_FAILURE_INNER(block_) EXPECT_CHECK_FAILURE(block_)

#endif

using CheckedMutexTypes = ::testing::Types<
  yamc::checked::mutex,
  yamc::checked::timed_mutex,
  yamc::checked::shared_mutex
>;

template <typename Mutex>
struct CheckedMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedMutexTest, CheckedMutexTypes);

// abandon mutex
TYPED_TEST(CheckedMutexTest, AbandonMutex) {
  EXPECT_CHECK_FAILURE({
    TypeParam mtx;
    mtx.lock();
    // no unlock()
  });
}

#if !TEST_PLATFORM_WINDOWS
// abandon mutex by other thread
TYPED_TEST(CheckedMutexTest, AbandonMutexSide) {
  EXPECT_CHECK_FAILURE_OUTER({
    yamc::test::barrier step(2);
    auto pmtx = yamc::cxx::make_unique<TypeParam>();
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(pmtx->lock());
      step.await();  // b1
      step.await();  // b2
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER({
        delete pmtx.release();
      });
      step.await();  // b2
    }
  });
}
#endif

// recurse lock() on non-recursive mutex
TYPED_TEST(CheckedMutexTest, RecurseLock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.lock());
  ASSERT_NO_THROW(mtx.unlock());
}

// recurse try_lock() on non-recursive mutex
TYPED_TEST(CheckedMutexTest, RecurseTryLock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock());
  ASSERT_NO_THROW(mtx.unlock());
}

// invalid unlock()
TYPED_TEST(CheckedMutexTest, InvalidUnlock0) {
  TypeParam mtx;
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// invalid unlock()
TYPED_TEST(CheckedMutexTest, InvalidUnlock1) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  ASSERT_NO_THROW(mtx.unlock());
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// non owner thread call unlock()
TYPED_TEST(CheckedMutexTest, NonOwnerUnlock) {
  EXPECT_CHECK_FAILURE_OUTER({
    yamc::test::barrier step(2);
    TypeParam mtx;
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(mtx.lock());
      step.await();  // b1
      step.await();  // b2
      ASSERT_NO_THROW(mtx.unlock());
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER(mtx.unlock());
      step.await();  // b2
    }
  });
}

using CheckedRecursiveMutexTypes = ::testing::Types<
  yamc::checked::recursive_mutex,
  yamc::checked::recursive_timed_mutex
>;

template <typename Mutex>
struct CheckedRecursiveMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedRecursiveMutexTest, CheckedRecursiveMutexTypes);

// abandon recursive_mutex
TYPED_TEST(CheckedRecursiveMutexTest, AbandonMutex) {
  EXPECT_CHECK_FAILURE({
    TypeParam mtx;
    mtx.lock();
    // no unlock()
  });
}

#if !TEST_PLATFORM_WINDOWS
// abandon mutex by other thread
TYPED_TEST(CheckedRecursiveMutexTest, AbandonMutexSide) {
  EXPECT_CHECK_FAILURE_OUTER({
    yamc::test::barrier step(2);
    auto pmtx = yamc::cxx::make_unique<TypeParam>();
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(pmtx->lock());
      step.await();  // b1
      step.await();  // b2
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER({
        delete pmtx.release();
      });
      step.await();  // b2
    }
  });
}
#endif

// invalid unlock()
TYPED_TEST(CheckedRecursiveMutexTest, InvalidUnlock0) {
  TypeParam mtx;
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// invalid unlock()
TYPED_TEST(CheckedRecursiveMutexTest, InvalidUnlock1) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());    // lockcnt = 1
  ASSERT_NO_THROW(mtx.unlock());  // lockcnt = 0
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// invalid unlock()
TYPED_TEST(CheckedRecursiveMutexTest, InvalidUnlock2) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());    // lockcnt = 1
  ASSERT_NO_THROW(mtx.lock());    // lockcnt = 2
  ASSERT_NO_THROW(mtx.unlock());  // lockcnt = 1
  ASSERT_NO_THROW(mtx.unlock());  // lockcnt = 0
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// non owner thread call unlock()
TYPED_TEST(CheckedRecursiveMutexTest, NonOwnerUnlock) {
  EXPECT_CHECK_FAILURE_OUTER({
    yamc::test::barrier step(2);
    TypeParam mtx;
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(mtx.lock());
      step.await();  // b1
      step.await();  // b2
      ASSERT_NO_THROW(mtx.unlock());
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER(mtx.unlock());
      step.await();  // b2
    }
  });
}

using CheckedTimedMutexTypes = ::testing::Types<
  yamc::checked::timed_mutex,
  yamc::checked::shared_timed_mutex
>;

template <typename Mutex>
struct CheckedTimedMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedTimedMutexTest, CheckedTimedMutexTypes);

// recurse try_lock_for() on non-recursive mutex
TYPED_TEST(CheckedTimedMutexTest, RecurseTryLockFor) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_for(std::chrono::seconds(1)));
  ASSERT_NO_THROW(mtx.unlock());
}

// recurse try_lock_until() on non-recursive mutex
TYPED_TEST(CheckedTimedMutexTest, RecurseTryLockUntil) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_until(std::chrono::system_clock::now()));
  ASSERT_NO_THROW(mtx.unlock());
}

using CheckedSharedMutexTypes = ::testing::Types<
  yamc::checked::shared_mutex,
  yamc::checked::shared_timed_mutex
>;

template <typename Mutex>
struct CheckedSharedMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedSharedMutexTest, CheckedSharedMutexTypes);

// abandon mutex
TYPED_TEST(CheckedSharedMutexTest, AbandonMutex) {
  EXPECT_CHECK_FAILURE({
    TypeParam mtx;
    mtx.lock_shared();
    // no unlock()
  });
}

#if !TEST_PLATFORM_WINDOWS
// abandon mutex by other thread
TYPED_TEST(CheckedSharedMutexTest, AbandonMutexSide) {
  EXPECT_CHECK_FAILURE_OUTER({
    yamc::test::barrier step(2);
    auto pmtx = yamc::cxx::make_unique<TypeParam>();
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(pmtx->lock_shared());
      step.await();  // b1
      step.await();  // b2
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER({
        delete pmtx.release();
      });
      step.await();  // b2
    }
  });
}
#endif

// recurse lock_shared()
TYPED_TEST(CheckedSharedMutexTest, RecurseLockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.lock_shared());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// recurse try_lock_shared()
TYPED_TEST(CheckedSharedMutexTest, RecurseTryLockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// lock() to lock_shared()
TYPED_TEST(CheckedSharedMutexTest, LockToLockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.lock_shared());
  ASSERT_NO_THROW(mtx.unlock());
}

// lock() to try_lock_shared()
TYPED_TEST(CheckedSharedMutexTest, LockToTryLockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared());
  ASSERT_NO_THROW(mtx.unlock());
}

// lock_shared() to lock()
TYPED_TEST(CheckedSharedMutexTest, LockSharedToLock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.lock());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// lock_shared() to try_lock()
TYPED_TEST(CheckedSharedMutexTest, LockSharedToTryLock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// unmatch unlock()
TYPED_TEST(CheckedSharedMutexTest, UnmatchUnlock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.unlock());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// unmatch unlock_shared()
TYPED_TEST(CheckedSharedMutexTest, UnmatchUnlockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.unlock_shared());
  ASSERT_NO_THROW(mtx.unlock());
}

// invalid unlock_shared()
TYPED_TEST(CheckedSharedMutexTest, InvalidUnlockShared0) {
  TypeParam mtx;
  EXPECT_CHECK_FAILURE(mtx.unlock_shared());
}

// invalid unlock_shared()
TYPED_TEST(CheckedSharedMutexTest, InvalidUnlockShared1) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  ASSERT_NO_THROW(mtx.unlock_shared());
  EXPECT_CHECK_FAILURE(mtx.unlock_shared());
}

// non owner thread call unlock_shared()
TYPED_TEST(CheckedSharedMutexTest, NonOwnerUnlockShared) {
  EXPECT_CHECK_FAILURE_OUTER({
    yamc::test::barrier step(2);
    TypeParam mtx;
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(mtx.lock_shared());
      step.await();  // b1
      step.await();  // b2
      ASSERT_NO_THROW(mtx.unlock_shared());
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER(mtx.unlock_shared());
      step.await();  // b2
    }
  });
}

using CheckedSharedTimedMutexTypes = ::testing::Types<
  yamc::checked::shared_timed_mutex
>;

template <typename Mutex>
struct CheckedSharedTimedMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedSharedTimedMutexTest, CheckedSharedTimedMutexTypes);

// recurse try_lock_shared_for()
TYPED_TEST(CheckedSharedTimedMutexTest, RecurseTryLockSharedFor) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared_for(std::chrono::seconds(1)));
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// recurse try_lock_shared_until()
TYPED_TEST(CheckedSharedTimedMutexTest, RecurseTryLockSharedUntil) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared_until(std::chrono::system_clock::now()));
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// lock() to try_lock_shared_for()
TYPED_TEST(CheckedSharedTimedMutexTest, LockToTryLockSharedFor) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared_for(std::chrono::seconds(1)));
  ASSERT_NO_THROW(mtx.unlock());
}

// lock() to try_lock_shared_until()
TYPED_TEST(CheckedSharedTimedMutexTest, LockToTryLockSharedUntil) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared_until(std::chrono::system_clock::now()));
  ASSERT_NO_THROW(mtx.unlock());
}

// lock_shared() to try_lock_for()
TYPED_TEST(CheckedSharedTimedMutexTest, LockSharedToTryLockFor) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_for(std::chrono::seconds(1)));
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// lock_shared() to try_lock_until()
TYPED_TEST(CheckedSharedTimedMutexTest, LockSharedToTryLockUntil) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_until(std::chrono::system_clock::now()));
  ASSERT_NO_THROW(mtx.unlock_shared());
}
<commit_msg>fix compile error on gcc (checked_test.cpp)<commit_after>/*
 * checked_test.cpp
 */
#include <chrono>
#include <system_error>
#include "gtest/gtest.h"
#include "checked_mutex.hpp"
#include "checked_shared_mutex.hpp"
#include "yamc_testutil.hpp"

#if YAMC_CHECKED_CALL_ABORT
// call std::abort() on check failure
#if TEST_PLATFORM_WINDOWS
//
// NOTE:
//   Some death tests (*.AbandonMutexSide) does not work correctly on Windows platform.
//
#define EXPECT_CHECK_FAILURE(statement_) EXPECT_EXIT(statement_, ::testing::ExitedWithCode(3), "")
#else
#define EXPECT_CHECK_FAILURE(statement_) EXPECT_EXIT(statement_, ::testing::KilledBySignal(SIGABRT), "")
#endif
#define EXPECT_CHECK_FAILURE_OUTER(block_) EXPECT_CHECK_FAILURE(block_)
#define EXPECT_CHECK_FAILURE_INNER(block_) block_

#else
// throw an exception on check failure
#define EXPECT_CHECK_FAILURE(statement_) EXPECT_THROW(statement_, std::system_error)
#define EXPECT_CHECK_FAILURE_OUTER(block_) block_
#define EXPECT_CHECK_FAILURE_INNER(block_) EXPECT_CHECK_FAILURE(block_)

#endif

using CheckedMutexTypes = ::testing::Types<
  yamc::checked::mutex,
  yamc::checked::timed_mutex,
  yamc::checked::shared_mutex
>;

template <typename Mutex>
struct CheckedMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedMutexTest, CheckedMutexTypes);

// abandon mutex
TYPED_TEST(CheckedMutexTest, AbandonMutex) {
  EXPECT_CHECK_FAILURE({
    TypeParam mtx;
    mtx.lock();
    // no unlock()
  });
}

#if !TEST_PLATFORM_WINDOWS
// abandon mutex by other thread
TYPED_TEST(CheckedMutexTest, AbandonMutexSide) {
  auto test_body = []{
    yamc::test::barrier step(2);
    auto pmtx = yamc::cxx::make_unique<TypeParam>();
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(pmtx->lock());
      step.await();  // b1
      step.await();  // b2
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER({
        delete pmtx.release();
      });
      step.await();  // b2
    }
  };
  EXPECT_CHECK_FAILURE_OUTER(test_body());
}
#endif

// recurse lock() on non-recursive mutex
TYPED_TEST(CheckedMutexTest, RecurseLock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.lock());
  ASSERT_NO_THROW(mtx.unlock());
}

// recurse try_lock() on non-recursive mutex
TYPED_TEST(CheckedMutexTest, RecurseTryLock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock());
  ASSERT_NO_THROW(mtx.unlock());
}

// invalid unlock()
TYPED_TEST(CheckedMutexTest, InvalidUnlock0) {
  TypeParam mtx;
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// invalid unlock()
TYPED_TEST(CheckedMutexTest, InvalidUnlock1) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  ASSERT_NO_THROW(mtx.unlock());
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// non owner thread call unlock()
TYPED_TEST(CheckedMutexTest, NonOwnerUnlock) {
  auto test_body = []{
    yamc::test::barrier step(2);
    TypeParam mtx;
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(mtx.lock());
      step.await();  // b1
      step.await();  // b2
      ASSERT_NO_THROW(mtx.unlock());
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER(mtx.unlock());
      step.await();  // b2
    }
  };
  EXPECT_CHECK_FAILURE_OUTER(test_body());
}

using CheckedRecursiveMutexTypes = ::testing::Types<
  yamc::checked::recursive_mutex,
  yamc::checked::recursive_timed_mutex
>;

template <typename Mutex>
struct CheckedRecursiveMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedRecursiveMutexTest, CheckedRecursiveMutexTypes);

// abandon recursive_mutex
TYPED_TEST(CheckedRecursiveMutexTest, AbandonMutex) {
  EXPECT_CHECK_FAILURE({
    TypeParam mtx;
    mtx.lock();
    // no unlock()
  });
}

#if !TEST_PLATFORM_WINDOWS
// abandon mutex by other thread
TYPED_TEST(CheckedRecursiveMutexTest, AbandonMutexSide) {
  auto test_body = []{
    yamc::test::barrier step(2);
    auto pmtx = yamc::cxx::make_unique<TypeParam>();
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(pmtx->lock());
      step.await();  // b1
      step.await();  // b2
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER({
        delete pmtx.release();
      });
      step.await();  // b2
    }
  };
  EXPECT_CHECK_FAILURE_OUTER(test_body());
}
#endif

// invalid unlock()
TYPED_TEST(CheckedRecursiveMutexTest, InvalidUnlock0) {
  TypeParam mtx;
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// invalid unlock()
TYPED_TEST(CheckedRecursiveMutexTest, InvalidUnlock1) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());    // lockcnt = 1
  ASSERT_NO_THROW(mtx.unlock());  // lockcnt = 0
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// invalid unlock()
TYPED_TEST(CheckedRecursiveMutexTest, InvalidUnlock2) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());    // lockcnt = 1
  ASSERT_NO_THROW(mtx.lock());    // lockcnt = 2
  ASSERT_NO_THROW(mtx.unlock());  // lockcnt = 1
  ASSERT_NO_THROW(mtx.unlock());  // lockcnt = 0
  EXPECT_CHECK_FAILURE(mtx.unlock());
}

// non owner thread call unlock()
TYPED_TEST(CheckedRecursiveMutexTest, NonOwnerUnlock) {
  auto test_body = []{
    yamc::test::barrier step(2);
    TypeParam mtx;
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(mtx.lock());
      step.await();  // b1
      step.await();  // b2
      ASSERT_NO_THROW(mtx.unlock());
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER(mtx.unlock());
      step.await();  // b2
    }
  };
  EXPECT_CHECK_FAILURE_OUTER(test_body());
}

using CheckedTimedMutexTypes = ::testing::Types<
  yamc::checked::timed_mutex,
  yamc::checked::shared_timed_mutex
>;

template <typename Mutex>
struct CheckedTimedMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedTimedMutexTest, CheckedTimedMutexTypes);

// recurse try_lock_for() on non-recursive mutex
TYPED_TEST(CheckedTimedMutexTest, RecurseTryLockFor) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_for(std::chrono::seconds(1)));
  ASSERT_NO_THROW(mtx.unlock());
}

// recurse try_lock_until() on non-recursive mutex
TYPED_TEST(CheckedTimedMutexTest, RecurseTryLockUntil) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_until(std::chrono::system_clock::now()));
  ASSERT_NO_THROW(mtx.unlock());
}

using CheckedSharedMutexTypes = ::testing::Types<
  yamc::checked::shared_mutex,
  yamc::checked::shared_timed_mutex
>;

template <typename Mutex>
struct CheckedSharedMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedSharedMutexTest, CheckedSharedMutexTypes);

// abandon mutex
TYPED_TEST(CheckedSharedMutexTest, AbandonMutex) {
  EXPECT_CHECK_FAILURE({
    TypeParam mtx;
    mtx.lock_shared();
    // no unlock()
  });
}

#if !TEST_PLATFORM_WINDOWS
// abandon mutex by other thread
TYPED_TEST(CheckedSharedMutexTest, AbandonMutexSide) {
  auto test_body = []{
    yamc::test::barrier step(2);
    auto pmtx = yamc::cxx::make_unique<TypeParam>();
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(pmtx->lock_shared());
      step.await();  // b1
      step.await();  // b2
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER({
        delete pmtx.release();
      });
      step.await();  // b2
    }
  };
  EXPECT_CHECK_FAILURE_OUTER(test_body());
}
#endif

// recurse lock_shared()
TYPED_TEST(CheckedSharedMutexTest, RecurseLockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.lock_shared());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// recurse try_lock_shared()
TYPED_TEST(CheckedSharedMutexTest, RecurseTryLockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// lock() to lock_shared()
TYPED_TEST(CheckedSharedMutexTest, LockToLockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.lock_shared());
  ASSERT_NO_THROW(mtx.unlock());
}

// lock() to try_lock_shared()
TYPED_TEST(CheckedSharedMutexTest, LockToTryLockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared());
  ASSERT_NO_THROW(mtx.unlock());
}

// lock_shared() to lock()
TYPED_TEST(CheckedSharedMutexTest, LockSharedToLock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.lock());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// lock_shared() to try_lock()
TYPED_TEST(CheckedSharedMutexTest, LockSharedToTryLock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// unmatch unlock()
TYPED_TEST(CheckedSharedMutexTest, UnmatchUnlock) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.unlock());
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// unmatch unlock_shared()
TYPED_TEST(CheckedSharedMutexTest, UnmatchUnlockShared) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.unlock_shared());
  ASSERT_NO_THROW(mtx.unlock());
}

// invalid unlock_shared()
TYPED_TEST(CheckedSharedMutexTest, InvalidUnlockShared0) {
  TypeParam mtx;
  EXPECT_CHECK_FAILURE(mtx.unlock_shared());
}

// invalid unlock_shared()
TYPED_TEST(CheckedSharedMutexTest, InvalidUnlockShared1) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  ASSERT_NO_THROW(mtx.unlock_shared());
  EXPECT_CHECK_FAILURE(mtx.unlock_shared());
}

// non owner thread call unlock_shared()
TYPED_TEST(CheckedSharedMutexTest, NonOwnerUnlockShared) {
  auto test_body = []{
    yamc::test::barrier step(2);
    TypeParam mtx;
    // owner-thread
    yamc::test::join_thread thd([&]{
      ASSERT_NO_THROW(mtx.lock_shared());
      step.await();  // b1
      step.await();  // b2
      ASSERT_NO_THROW(mtx.unlock_shared());
    });
    // other-thread
    {
      step.await();  // b1
      EXPECT_CHECK_FAILURE_INNER(mtx.unlock_shared());
      step.await();  // b2
    }
  };
  EXPECT_CHECK_FAILURE_OUTER(test_body());
}

using CheckedSharedTimedMutexTypes = ::testing::Types<
  yamc::checked::shared_timed_mutex
>;

template <typename Mutex>
struct CheckedSharedTimedMutexTest : ::testing::Test {};

TYPED_TEST_CASE(CheckedSharedTimedMutexTest, CheckedSharedTimedMutexTypes);

// recurse try_lock_shared_for()
TYPED_TEST(CheckedSharedTimedMutexTest, RecurseTryLockSharedFor) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared_for(std::chrono::seconds(1)));
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// recurse try_lock_shared_until()
TYPED_TEST(CheckedSharedTimedMutexTest, RecurseTryLockSharedUntil) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared_until(std::chrono::system_clock::now()));
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// lock() to try_lock_shared_for()
TYPED_TEST(CheckedSharedTimedMutexTest, LockToTryLockSharedFor) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared_for(std::chrono::seconds(1)));
  ASSERT_NO_THROW(mtx.unlock());
}

// lock() to try_lock_shared_until()
TYPED_TEST(CheckedSharedTimedMutexTest, LockToTryLockSharedUntil) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock());
  EXPECT_CHECK_FAILURE(mtx.try_lock_shared_until(std::chrono::system_clock::now()));
  ASSERT_NO_THROW(mtx.unlock());
}

// lock_shared() to try_lock_for()
TYPED_TEST(CheckedSharedTimedMutexTest, LockSharedToTryLockFor) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_for(std::chrono::seconds(1)));
  ASSERT_NO_THROW(mtx.unlock_shared());
}

// lock_shared() to try_lock_until()
TYPED_TEST(CheckedSharedTimedMutexTest, LockSharedToTryLockUntil) {
  TypeParam mtx;
  ASSERT_NO_THROW(mtx.lock_shared());
  EXPECT_CHECK_FAILURE(mtx.try_lock_until(std::chrono::system_clock::now()));
  ASSERT_NO_THROW(mtx.unlock_shared());
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: helpagentwindow.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 15:10:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#ifndef _SVTOOLS_HELPAGENTWIDNOW_HXX_
#include "helpagentwindow.hxx"
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SV_BITMAP_HXX
#include <vcl/bitmap.hxx>
#endif
#ifndef _SVTOOLS_SVTDATA_HXX
#include <svtdata.hxx>
#endif

#ifndef _SVTOOLS_HRC
#include "svtools.hrc"
#endif
#ifndef _SVT_HELPID_HRC
#include "helpid.hrc"
#endif

#define WB_AGENT_STYLE  0

//........................................................................
namespace svt
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::awt;
    using namespace ::com::sun::star::lang;

    //====================================================================
    //= CloserButton_Impl
    //= overload of ImageButton, because sometimes vcl doesn't call the click handler
    //====================================================================
    //--------------------------------------------------------------------
    class CloserButton_Impl : public ImageButton
    {
    public:
        CloserButton_Impl( Window* pParent, WinBits nBits ) : ImageButton( pParent, nBits ) {}

        virtual void        MouseButtonUp( const MouseEvent& rMEvt );
    };

    //--------------------------------------------------------------------
    void CloserButton_Impl::MouseButtonUp( const MouseEvent& rMEvt )
    {
        ImageButton::MouseButtonUp( rMEvt );
        GetClickHdl().Call( this );
    }

    //====================================================================
    //= HelpAgentWindow
    //====================================================================
    //--------------------------------------------------------------------
    HelpAgentWindow::HelpAgentWindow( Window* _pParent )
        :FloatingWindow( _pParent, WB_AGENT_STYLE)
        ,m_pCloser(NULL)
        ,m_pCallback(NULL)
    {
        // -----------------
        // the closer button
        Bitmap aCloserBitmap(SvtResId(BMP_HELP_AGENT_CLOSER));
        Image aCloserImage( aCloserBitmap, Color(COL_LIGHTMAGENTA) );
        m_pCloser = new CloserButton_Impl( this, WB_NOTABSTOP | WB_NOPOINTERFOCUS );
        static_cast<CloserButton_Impl*>(m_pCloser)->SetModeImage( aCloserImage );
        static_cast<CloserButton_Impl*>(m_pCloser)->SetClickHdl( LINK(this, HelpAgentWindow, OnButtonClicked) );
        m_pCloser->SetSizePixel( implOptimalButtonSize(aCloserImage) );
        m_pCloser->Show();
        m_pCloser->SetZOrder( NULL, WINDOW_ZORDER_LAST );

        // ----------------------------
        // calculate our preferred size
        Bitmap aHelpAgentBitmap(SvtResId(BMP_HELP_AGENT_IMAGE));
        m_aPicture = Image( aHelpAgentBitmap );
        m_aPreferredSize = m_aPicture.GetSizePixel();
        m_aPreferredSize.Width() += 2;
        m_aPreferredSize.Height() += 2;

        Size aSize = GetSizePixel();
        Size aOutputSize = GetOutputSizePixel();
        m_aPreferredSize.Width() += aSize.Width() - aOutputSize.Width();
        m_aPreferredSize.Height() += aSize.Height() - aOutputSize.Height();

        SetPointer(Pointer(POINTER_REFHAND));
        AlwaysEnableInput( TRUE, TRUE );

        // unique id for the testtool
        SetUniqueId( HID_HELPAGENT_WINDOW );
    }

    //--------------------------------------------------------------------
    HelpAgentWindow::~HelpAgentWindow()
    {
        if (m_pCloser && m_pCloser->IsTracking())
            m_pCloser->EndTracking();
        if (m_pCloser && m_pCloser->IsMouseCaptured())
            m_pCloser->ReleaseMouse();

        delete m_pCloser;
    }

    //--------------------------------------------------------------------
    void HelpAgentWindow::Paint( const Rectangle& rRect )
    {
        FloatingWindow::Paint(rRect);

        Size        aOutputSize( GetOutputSizePixel() );
        Point       aPoint=Point();
        Rectangle   aOutputRect( aPoint, aOutputSize );
        Rectangle   aInnerRect( aOutputRect );

        // paint the background
        SetLineColor( GetSettings().GetStyleSettings().GetFaceColor() );
        SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
        DrawRect( aOutputRect );

        // paint the image
        Size aPictureSize( m_aPicture.GetSizePixel() );
        Point aPicturePos(
            aOutputRect.Left() + (aInnerRect.GetWidth() - aPictureSize.Width()) / 2,
            aOutputRect.Top() + (aInnerRect.GetHeight() - aPictureSize.Height()) / 2 );

        DrawImage( aPicturePos, m_aPicture, 0 );
    }

    //--------------------------------------------------------------------
    void HelpAgentWindow::MouseButtonUp( const MouseEvent& rMEvt )
    {
        FloatingWindow::MouseButtonUp(rMEvt);

        if (m_pCallback)
            m_pCallback->helpRequested();
    }

    //--------------------------------------------------------------------
    Size HelpAgentWindow::implOptimalButtonSize( const Image& _rButtonImage )
    {
        Size aPreferredSize = _rButtonImage.GetSizePixel();
        // add a small frame, needed by the button
        aPreferredSize.Width() += 5;
        aPreferredSize.Height() += 5;
        return aPreferredSize;
    }

    //--------------------------------------------------------------------
    void HelpAgentWindow::Resize()
    {
        FloatingWindow::Resize();

        Size aOutputSize = GetOutputSizePixel();
        Size aCloserSize = m_pCloser->GetSizePixel();
        if (m_pCloser)
            m_pCloser->SetPosPixel( Point(aOutputSize.Width() - aCloserSize.Width() - 3, 4) );
    }

    //--------------------------------------------------------------------
    IMPL_LINK( HelpAgentWindow, OnButtonClicked, Window*, _pWhichOne )
    {
        if (m_pCloser == _pWhichOne)
            if (m_pCallback)
                m_pCallback->closeAgent();
        return 0L;
    }

//........................................................................
}   // namespace svt
//........................................................................

<commit_msg>INTEGRATION: CWS vgbugs07 (1.11.200); FILE MERGED 2007/06/04 13:31:43 vg 1.11.200.1: #i76605# Remove -I .../inc/module hack introduced by hedaburemove01<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: helpagentwindow.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-27 21:50:13 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#ifndef _SVTOOLS_HELPAGENTWIDNOW_HXX_
#include "helpagentwindow.hxx"
#endif

#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif
#ifndef _SV_BITMAP_HXX
#include <vcl/bitmap.hxx>
#endif
#ifndef _SVTOOLS_SVTDATA_HXX
#include <svtools/svtdata.hxx>
#endif

#ifndef _SVTOOLS_HRC
#include <svtools/svtools.hrc>
#endif
#ifndef _SVT_HELPID_HRC
#include <svtools/helpid.hrc>
#endif

#define WB_AGENT_STYLE  0

//........................................................................
namespace svt
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::awt;
    using namespace ::com::sun::star::lang;

    //====================================================================
    //= CloserButton_Impl
    //= overload of ImageButton, because sometimes vcl doesn't call the click handler
    //====================================================================
    //--------------------------------------------------------------------
    class CloserButton_Impl : public ImageButton
    {
    public:
        CloserButton_Impl( Window* pParent, WinBits nBits ) : ImageButton( pParent, nBits ) {}

        virtual void        MouseButtonUp( const MouseEvent& rMEvt );
    };

    //--------------------------------------------------------------------
    void CloserButton_Impl::MouseButtonUp( const MouseEvent& rMEvt )
    {
        ImageButton::MouseButtonUp( rMEvt );
        GetClickHdl().Call( this );
    }

    //====================================================================
    //= HelpAgentWindow
    //====================================================================
    //--------------------------------------------------------------------
    HelpAgentWindow::HelpAgentWindow( Window* _pParent )
        :FloatingWindow( _pParent, WB_AGENT_STYLE)
        ,m_pCloser(NULL)
        ,m_pCallback(NULL)
    {
        // -----------------
        // the closer button
        Bitmap aCloserBitmap(SvtResId(BMP_HELP_AGENT_CLOSER));
        Image aCloserImage( aCloserBitmap, Color(COL_LIGHTMAGENTA) );
        m_pCloser = new CloserButton_Impl( this, WB_NOTABSTOP | WB_NOPOINTERFOCUS );
        static_cast<CloserButton_Impl*>(m_pCloser)->SetModeImage( aCloserImage );
        static_cast<CloserButton_Impl*>(m_pCloser)->SetClickHdl( LINK(this, HelpAgentWindow, OnButtonClicked) );
        m_pCloser->SetSizePixel( implOptimalButtonSize(aCloserImage) );
        m_pCloser->Show();
        m_pCloser->SetZOrder( NULL, WINDOW_ZORDER_LAST );

        // ----------------------------
        // calculate our preferred size
        Bitmap aHelpAgentBitmap(SvtResId(BMP_HELP_AGENT_IMAGE));
        m_aPicture = Image( aHelpAgentBitmap );
        m_aPreferredSize = m_aPicture.GetSizePixel();
        m_aPreferredSize.Width() += 2;
        m_aPreferredSize.Height() += 2;

        Size aSize = GetSizePixel();
        Size aOutputSize = GetOutputSizePixel();
        m_aPreferredSize.Width() += aSize.Width() - aOutputSize.Width();
        m_aPreferredSize.Height() += aSize.Height() - aOutputSize.Height();

        SetPointer(Pointer(POINTER_REFHAND));
        AlwaysEnableInput( TRUE, TRUE );

        // unique id for the testtool
        SetUniqueId( HID_HELPAGENT_WINDOW );
    }

    //--------------------------------------------------------------------
    HelpAgentWindow::~HelpAgentWindow()
    {
        if (m_pCloser && m_pCloser->IsTracking())
            m_pCloser->EndTracking();
        if (m_pCloser && m_pCloser->IsMouseCaptured())
            m_pCloser->ReleaseMouse();

        delete m_pCloser;
    }

    //--------------------------------------------------------------------
    void HelpAgentWindow::Paint( const Rectangle& rRect )
    {
        FloatingWindow::Paint(rRect);

        Size        aOutputSize( GetOutputSizePixel() );
        Point       aPoint=Point();
        Rectangle   aOutputRect( aPoint, aOutputSize );
        Rectangle   aInnerRect( aOutputRect );

        // paint the background
        SetLineColor( GetSettings().GetStyleSettings().GetFaceColor() );
        SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() );
        DrawRect( aOutputRect );

        // paint the image
        Size aPictureSize( m_aPicture.GetSizePixel() );
        Point aPicturePos(
            aOutputRect.Left() + (aInnerRect.GetWidth() - aPictureSize.Width()) / 2,
            aOutputRect.Top() + (aInnerRect.GetHeight() - aPictureSize.Height()) / 2 );

        DrawImage( aPicturePos, m_aPicture, 0 );
    }

    //--------------------------------------------------------------------
    void HelpAgentWindow::MouseButtonUp( const MouseEvent& rMEvt )
    {
        FloatingWindow::MouseButtonUp(rMEvt);

        if (m_pCallback)
            m_pCallback->helpRequested();
    }

    //--------------------------------------------------------------------
    Size HelpAgentWindow::implOptimalButtonSize( const Image& _rButtonImage )
    {
        Size aPreferredSize = _rButtonImage.GetSizePixel();
        // add a small frame, needed by the button
        aPreferredSize.Width() += 5;
        aPreferredSize.Height() += 5;
        return aPreferredSize;
    }

    //--------------------------------------------------------------------
    void HelpAgentWindow::Resize()
    {
        FloatingWindow::Resize();

        Size aOutputSize = GetOutputSizePixel();
        Size aCloserSize = m_pCloser->GetSizePixel();
        if (m_pCloser)
            m_pCloser->SetPosPixel( Point(aOutputSize.Width() - aCloserSize.Width() - 3, 4) );
    }

    //--------------------------------------------------------------------
    IMPL_LINK( HelpAgentWindow, OnButtonClicked, Window*, _pWhichOne )
    {
        if (m_pCloser == _pWhichOne)
            if (m_pCallback)
                m_pCallback->closeAgent();
        return 0L;
    }

//........................................................................
}   // namespace svt
//........................................................................

<|endoftext|>


<commit_before>#include <memory>
#include <gtest/gtest.h>
#include "mmap_allocator.h"

class MMapAllocatorTest : public testing::Test {
 protected:
  virtual void SetUp() {
    mmap_alloc_.reset(MMapAllocator<int>::New("test.db"));
  }

 std::unique_ptr<MMapAllocator<int>> mmap_alloc_;
};

TEST_F(MMapAllocatorTest, Vector) {
  std::vector<int, MMapAllocator<int>> vec(*mmap_alloc_);

  for (int i = 0; i < 10; ++i) {
    vec.push_back(i);
  }

  EXPECT_EQ(10, vec.size());

  for (int i = 0; i < vec.size(); ++i) {
    EXPECT_EQ(i, vec[i]);
  }
}

TEST_F(MMapAllocatorTest, VectorInitialized) {
  std::vector<int, MMapAllocator<int>> vec({4, 42, 24, 7}, *mmap_alloc_);

  EXPECT_EQ(4, vec.size());
  EXPECT_EQ(4, vec[0]);
  EXPECT_EQ(42, vec[1]);
  EXPECT_EQ(24, vec[2]);
  EXPECT_EQ(7, vec[3]);
}
<commit_msg>added some more tests<commit_after>#include <memory>
#include <gtest/gtest.h>
#include "mmap_allocator.h"

class MMapAllocatorTest : public testing::Test {
 protected:
  template<class T>
  std::unique_ptr<MMapAllocator<T>> make_allocator() {
    return std::unique_ptr<MMapAllocator<T>>(MMapAllocator<T>::New("test.db"));
  }

  template<class T>
  std::vector<T, MMapAllocator<T>> make_vector(MMapAllocator<T>* alloc) {
    return std::vector<T, MMapAllocator<T>>(*alloc);
  }
};

TEST_F(MMapAllocatorTest, VectorInt) {
  // std::unique_ptr<MMapAllocator<int>> alloc(MMapAllocator<int>::New("test.db"));
  auto alloc = make_allocator<int>();
  auto vec = make_vector<int>(alloc.get());

  for (int i = 0; i < 10; ++i) {
    vec.push_back(i);
  }

  EXPECT_EQ(10, vec.size());

  for (int i = 0; i < vec.size(); ++i) {
    EXPECT_EQ(i, vec[i]);
  }
}

TEST_F(MMapAllocatorTest, VectorIntInitialized) {
  auto alloc = make_allocator<int>();
  std::vector<int, MMapAllocator<int>> vec({4, 42, 24, 7}, *alloc);

  EXPECT_EQ(4, vec.size());
  EXPECT_EQ(4, vec[0]);
  EXPECT_EQ(42, vec[1]);
  EXPECT_EQ(24, vec[2]);
  EXPECT_EQ(7, vec[3]);
}

TEST_F(MMapAllocatorTest, VectorDouble) {
  auto alloc = make_allocator<double>();
  auto vec = make_vector<double>(alloc.get());

  for (int i = 0; i < 10; ++i) {
    vec.push_back(sqrt(i));
  }

  EXPECT_EQ(10, vec.size());

  for (int i = 0; i < vec.size(); ++i) {
    EXPECT_EQ(sqrt(i), vec[i]);
  }
}

TEST_F(MMapAllocatorTest, VectorString) {
  auto alloc = make_allocator<std::string>();
  auto vec = make_vector<std::string>(alloc.get());

  for (int i = 0; i < 10; ++i) {
    vec.push_back("Hello, world!");
  }

  EXPECT_EQ(10, vec.size());

  for (int i = 0; i < vec.size(); ++i) {
    EXPECT_EQ("Hello, world!", vec[i]);
  }
}
<|endoftext|>


<commit_before>#include "debugger.h"
#include "dbg_impl.h"
#include "dbg_network.h"
#include "dbg_delayload.h"
#include "dbg_unicode.h"

namespace vscode
{
	debugger::debugger(io* io, threadmode mode)
		: impl_(new debugger_impl(io, mode))
	{ }

	debugger::~debugger()
	{
		delete impl_;
	}

	void debugger::update()
	{
		impl_->update();
	}

	void debugger::attach_lua(lua_State* L, bool pause)
	{
		impl_->attach_lua(L, pause);
	}

	void debugger::detach_lua(lua_State* L)
	{
		impl_->detach_lua(L);
	}

	void debugger::set_custom(custom* custom)
	{
		impl_->set_custom(custom);
	}

	void debugger::output(const char* category, const char* buf, size_t len)
	{
		impl_->output(category, buf, len);
	}
}

std::unique_ptr<vscode::network>  global_io;
std::unique_ptr<vscode::debugger> global_dbg;

void __cdecl set_luadll(const char* path, size_t len)
{
#if defined(DEBUGGER_DELAYLOAD_LUA)
	delayload::set_luadll(vscode::u2w(vscode::strview(path, len)));
#endif
}

uint16_t __cdecl start_server(const char* ip, uint16_t port, bool launch)
{
	if (!global_io || !global_dbg)
	{
		global_io.reset(new vscode::network(ip, port));
		global_dbg.reset(new vscode::debugger(global_io.get(), vscode::threadmode::async));
		if (launch)
			global_io->kill_process_when_close();
	}
	return global_io->get_port();
}

void __cdecl attach_lua(lua_State* L, bool pause)
{
	if (global_dbg) global_dbg->attach_lua(L, pause);
}

void __cdecl detach_lua(lua_State* L)
{
	if (global_dbg) global_dbg->detach_lua(L);
}

namespace luaw {
	int listen(lua_State* L)
	{
		::start_server(luaL_checkstring(L, 1), (uint16_t)luaL_checkinteger(L, 2), false);
		::attach_lua(L, false);
		lua_pushvalue(L, lua_upvalueindex(1));
		return 1;
	}

	int start(lua_State* L)
	{
		::attach_lua(L, true);
		lua_pushvalue(L, lua_upvalueindex(1));
		return 1;
	}

	int __gc(lua_State* L)
	{
		if (global_dbg) {
			global_dbg->detach_lua(L);
		}
		return 0;
	}

	int open(lua_State* L)
	{
		luaL_checkversion(L);
		luaL_Reg f[] = {
			{ "listen", listen },
			{ "start", start },
			{ "__gc", __gc },
			{ NULL, NULL },
		};
		luaL_newlibtable(L, f);
		lua_pushvalue(L, -1);
		luaL_setfuncs(L, f, 1);
		lua_pushvalue(L, -1);
		lua_setmetatable(L, -2);
		return 1;
	}
}

void caller_is_luadll(void* callerAddress)
{
	HMODULE  caller = NULL;
	if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)callerAddress, &caller) && caller)
	{
		if (GetProcAddress(caller, "lua_newstate"))
		{
			delayload::set_luadll(caller);
		}
	}
}

int __cdecl luaopen_debugger(lua_State* L)
{
#if defined(DEBUGGER_DELAYLOAD_LUA)
	caller_is_luadll(_ReturnAddress());
#endif
	return luaw::open(L);
}
<commit_msg>一个编译错误<commit_after>#include "debugger.h"
#include "dbg_impl.h"
#include "dbg_network.h"
#include "dbg_delayload.h"
#include "dbg_unicode.h"

namespace vscode
{
	debugger::debugger(io* io, threadmode mode)
		: impl_(new debugger_impl(io, mode))
	{ }

	debugger::~debugger()
	{
		delete impl_;
	}

	void debugger::update()
	{
		impl_->update();
	}

	void debugger::attach_lua(lua_State* L, bool pause)
	{
		impl_->attach_lua(L, pause);
	}

	void debugger::detach_lua(lua_State* L)
	{
		impl_->detach_lua(L);
	}

	void debugger::set_custom(custom* custom)
	{
		impl_->set_custom(custom);
	}

	void debugger::output(const char* category, const char* buf, size_t len)
	{
		impl_->output(category, buf, len);
	}
}

std::unique_ptr<vscode::network>  global_io;
std::unique_ptr<vscode::debugger> global_dbg;

void __cdecl set_luadll(const char* path, size_t len)
{
#if defined(DEBUGGER_DELAYLOAD_LUA)
	delayload::set_luadll(vscode::u2w(vscode::strview(path, len)));
#endif
}

uint16_t __cdecl start_server(const char* ip, uint16_t port, bool launch)
{
	if (!global_io || !global_dbg)
	{
		global_io.reset(new vscode::network(ip, port));
		global_dbg.reset(new vscode::debugger(global_io.get(), vscode::threadmode::async));
		if (launch)
			global_io->kill_process_when_close();
	}
	return global_io->get_port();
}

void __cdecl attach_lua(lua_State* L, bool pause)
{
	if (global_dbg) global_dbg->attach_lua(L, pause);
}

void __cdecl detach_lua(lua_State* L)
{
	if (global_dbg) global_dbg->detach_lua(L);
}

namespace luaw {
	int listen(lua_State* L)
	{
		::start_server(luaL_checkstring(L, 1), (uint16_t)luaL_checkinteger(L, 2), false);
		::attach_lua(L, false);
		lua_pushvalue(L, lua_upvalueindex(1));
		return 1;
	}

	int start(lua_State* L)
	{
		::attach_lua(L, true);
		lua_pushvalue(L, lua_upvalueindex(1));
		return 1;
	}

	int __gc(lua_State* L)
	{
		if (global_dbg) {
			global_dbg->detach_lua(L);
		}
		return 0;
	}

	int open(lua_State* L)
	{
		luaL_checkversion(L);
		luaL_Reg f[] = {
			{ "listen", listen },
			{ "start", start },
			{ "__gc", __gc },
			{ NULL, NULL },
		};
		luaL_newlibtable(L, f);
		lua_pushvalue(L, -1);
		luaL_setfuncs(L, f, 1);
		lua_pushvalue(L, -1);
		lua_setmetatable(L, -2);
		return 1;
	}
}

#if defined(DEBUGGER_DELAYLOAD_LUA)
void caller_is_luadll(void* callerAddress)
{
	HMODULE  caller = NULL;
	if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)callerAddress, &caller) && caller)
	{
		if (GetProcAddress(caller, "lua_newstate"))
		{
			delayload::set_luadll(caller);
		}
	}
}
#endif

int __cdecl luaopen_debugger(lua_State* L)
{
#if defined(DEBUGGER_DELAYLOAD_LUA)
	caller_is_luadll(_ReturnAddress());
#endif
	return luaw::open(L);
}
<|endoftext|>


<commit_before>#include "caffe2/share/contrib/observers/observer_config.h"

namespace caffe2 {

int ObserverConfig::netSampleRate_ = 1;
int ObserverConfig::operatorNetSampleRatio_ = 0;
int ObserverConfig::skipIters_ = 10;
unique_ptr<NetObserverReporter> ObserverConfig::reporter_ = nullptr;
int ObserverConfig::marker_ = -1;
}
<commit_msg>Disable logging by default<commit_after>#include "caffe2/share/contrib/observers/observer_config.h"

namespace caffe2 {

int ObserverConfig::netSampleRate_ = 0;
int ObserverConfig::operatorNetSampleRatio_ = 0;
int ObserverConfig::skipIters_ = 0;
unique_ptr<NetObserverReporter> ObserverConfig::reporter_ = nullptr;
int ObserverConfig::marker_ = -1;
}
<|endoftext|>