<commit_before>/**
* @file Simulation.cpp
* @author Benjamin Schlotter
* Implementation of class Simulation
*/

#include "Simulation.h"

using namespace naoth;
using namespace std;

Simulation::Simulation()
{
  DEBUG_REQUEST_REGISTER("Simulation:draw_one_action_point:global","draw_one_action_point:global", false);
  DEBUG_REQUEST_REGISTER("Simulation:draw_ball","draw_ball", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget","ActionTarget", false);
  DEBUG_REQUEST_REGISTER("Simulation:draw_best_action","best action",false);
  //DEBUG_REQUEST_REGISTER("Simulation:draw_pessimistic_best_action","best pessimistic action",false);
  DEBUG_REQUEST_REGISTER("Simulation:GoalLinePreview","GoalLinePreview",false);
  DEBUG_REQUEST_REGISTER("Simulation:draw_potential_field","Draw Potential Field",false);
  DEBUG_REQUEST_REGISTER("Simulation:use_Parameters","use_Parameters",false);

  getDebugParameterList().add(&theParameters);

  //actionRingBuffer.resize(ActionModel::numOfActions);
  //calculate the actions
  action_local.reserve(KickActionModel::numOfActions);

  action_local.push_back(Action(KickActionModel::none, Vector2d()));
  action_local.push_back(Action(KickActionModel::kick_long, Vector2d(theParameters.action_long_kick_distance, 0))); // long
  action_local.push_back(Action(KickActionModel::kick_short, Vector2d(theParameters.action_short_kick_distance, 0))); // short
  action_local.push_back(Action(KickActionModel::sidekick_right, Vector2d(0, -theParameters.action_sidekick_distance))); // right
  action_local.push_back(Action(KickActionModel::sidekick_left, Vector2d(0, theParameters.action_sidekick_distance))); // left
}

Simulation::~Simulation(){}

void Simulation::execute()
{
  DEBUG_REQUEST("Simulation:use_Parameters",
  action_local.clear();
  action_local.reserve(KickActionModel::numOfActions);

  action_local.push_back(Action(KickActionModel::none, Vector2d()));
  action_local.push_back(Action(KickActionModel::kick_long, Vector2d(theParameters.action_long_kick_distance, 0))); // long
  action_local.push_back(Action(KickActionModel::kick_short, Vector2d(theParameters.action_short_kick_distance, 0))); // short
  action_local.push_back(Action(KickActionModel::sidekick_right, Vector2d(0, -theParameters.action_sidekick_distance))); // right
  action_local.push_back(Action(KickActionModel::sidekick_left, Vector2d(0, theParameters.action_sidekick_distance))); // left
  );

  if(!getBallModel().valid || getFrameInfo().getTimeInSeconds() >= getBallModel().frameInfoWhenBallWasSeen.getTimeInSeconds()+1)
  {
    return;
  }
  else
  {
    int best_action = 0;

    for(size_t i=0; i<action_local.size(); i++)
    {
      // physics simulator
      std::vector<Vector2d> ballPositionResults;
      for(size_t j=0; j<30; j++)
      {
        const Vector2d& ballRelativePreview = getBallModel().positionPreview;
        Vector2d ballPositionResult = action_local[i].predict(ballRelativePreview, theParameters.distance_variance, theParameters.angle_variance);
        ballPositionResults.push_back(ballPositionResult);
      }

      // categorize positions
      std::vector<CategorizedBallPosition> categorizedBallPositionResults;
      for(std::vector<Vector2d>::iterator ballPosition = ballPositionResults.begin(); ballPosition != ballPositionResults.end(); ballPosition++)
      {
        BallPositionCategory category = this->categorizePosition(*ballPosition);
        CategorizedBallPosition categorizedBallPosition = CategorizedBallPosition(*ballPosition, category);
        categorizedBallPositionResults.push_back(categorizedBallPosition);
      }
    }

    getKickActionModel().myAction = action_local[best_action].id();

    DEBUG_REQUEST("Simulation:draw_best_action",
    {
      FIELD_DRAWING_CONTEXT;
      PEN("FF69B4", 7);
      Vector2d actionGlobal = action_local[best_action].target;
      FILLOVAL(actionGlobal.x, actionGlobal.y, 50,50);
    });

//  DEBUG_REQUEST("Simulation:draw_potential_field",
//     draw_potential_field();
//  );

  }
}//end execute

Simulation::BallPositionCategory Simulation::categorizePosition(const Vector2d& globalPoint) const
{
  Vector2d point = globalPoint;

  //Schusslinie
  Math::LineSegment shootLine(getBallModel().positionPreview, globalPoint);

  BallPositionCategory cat = INFIELD;
  if(getFieldInfo().fieldRect.inside(point)){
    return cat;
  } else
  {
    //Opponent Groundline Out - Ball einen Meter hinter Roboter mind ansto hhe. jeweils seite wo ins ausgeht
    if(point.x > getFieldInfo().xPosOpponentGroundline)
    {
      cat = OPPOUT;
    }
    //Own Groundline out -  an der seite wo raus geht
    else if(point.x < getFieldInfo().xPosOwnGroundline)
    {
      cat = OWNOUT;
    }
    //an der linken Seite raus -> ein meter hinter roboter oder wo ins ausgeht ein meter hinter
    else if(point.y > getFieldInfo().yPosLeftSideline )
    {
      cat = LEFTOUT;
    }
    //an der rechten Seite raus -> ein meter hinter roboter oder wo ins ausgeht ein meter hinter
    else if(point.y < getFieldInfo().yPosRightSideline)
    {
      cat = RIGHTOUT;
    }
    return cat;
  }
}

Vector2d Simulation::calculateOneAction(const Action& action) const
{
  // STEP 1: predict the action outcome
  const Vector2d& ballRelativePreview = getBallModel().positionPreview;

  DEBUG_REQUEST("Simulation:draw_ball",
    FIELD_DRAWING_CONTEXT;
    PEN("FF0000", 1);
    Vector2d ball = getRobotPose() * getBallModel().positionPreview;
    CIRCLE( ball.x, ball.y, 50);
  );

  Vector2d result = action.predict(ballRelativePreview, theParameters.distance_variance, theParameters.angle_variance);

  DEBUG_REQUEST("Simulation:ActionTarget",
    FIELD_DRAWING_CONTEXT;
    PEN("0000FF", 1);
    Vector2d ball = getRobotPose() * result;
    CIRCLE( ball.x, ball.y, 50);
  );

  // STEP 2: calculate the goal line
  GoalModel::Goal oppGoalModel = getSelfLocGoalModel().getOppGoal(getCompassDirection(), getFieldInfo());
  Vector2d oppGoalPostLeftPreview = getMotionStatus().plannedMotion.hip / oppGoalModel.leftPost;
  Vector2d oppGoalPostRightPreview = getMotionStatus().plannedMotion.hip / oppGoalModel.rightPost;

  //the endpoints of our line are a shortened version of the goal line
  Vector2d goalDir = (oppGoalPostRightPreview - oppGoalPostLeftPreview).normalize();
  Vector2d leftEndpoint = oppGoalPostLeftPreview + goalDir*(getFieldInfo().goalpostRadius + getFieldInfo().ballRadius);
  Vector2d rightEndpoint = oppGoalPostRightPreview - goalDir*(getFieldInfo().goalpostRadius + getFieldInfo().ballRadius);

  // this is the goalline we are shooting for
  Math::LineSegment goalLinePreview(leftEndpoint, rightEndpoint);

  // note: the drawing is global
  DEBUG_REQUEST("Simulation:GoalLinePreview",
    FIELD_DRAWING_CONTEXT;
    PEN("000000", 1);
    Vector2d globalLeft = getRobotPose() * leftEndpoint;
    Vector2d globalRight = getRobotPose() * rightEndpoint;
    LINE(globalLeft.x,globalLeft.y,globalRight.x,globalRight.y);
  );

  // STEP 3: estimate external factors (shooting a goal, ball moved by referee)
  //Math::LineSegment shootLine(ballRelativePreview, outsideField(lonely_action.target));//hmm
  Math::LineSegment shootLine(ballRelativePreview, result);

  Vector2d resultingBallPosition;

  if(shootLine.intersect(goalLinePreview) && goalLinePreview.intersect(shootLine)) {
    resultingBallPosition = Vector2d(getFieldInfo().xPosOpponentGoal+200, 0.0);
  } else {
    resultingBallPosition = outsideField(getRobotPose() * result);
  }

  return resultingBallPosition;
}

  //correction of distance in percentage, angle in degrees
  Vector2d Simulation::Action::predict(const Vector2d& ball, double distance_variance, double angle_variance) const
  {
  double random_length = 2.0*Math::random()-1.0;
  double random_angle = 2.0*Math::random()-1.0;

  Vector2d noisyAction = actionVector + actionVector*(distance_variance*random_length);
  noisyAction.rotate(angle_variance*random_angle);

  return ball + noisyAction;
  }

//calcualte according to the rules, without the roboter position, the ball position
//if it goes outside the field
Vector2d Simulation::outsideField(const Vector2d& globalPoint) const
{
  Vector2d point = globalPoint;

  //Schusslinie
  Math::LineSegment shootLine(getBallModel().positionPreview, globalPoint);

  if(getFieldInfo().fieldRect.inside(point)){
    return point;
  }
  else
      //Nach Prioritten geordnet - zuerst die Regeln mit dem mglichst schlimmsten Resultat
  {   //Opponent Groundline Out - Ball einen Meter hinter Roboter mind ansto hhe. jeweils seite wo ins ausgeht
      if(point.x > getFieldInfo().xPosOpponentGroundline)
      {
        Vector2d OppOutPoint = getFieldInfo().oppLineSegment.point(getFieldInfo().oppLineSegment.intersection(shootLine));
        if(OppOutPoint.y < 0)
        {
          return Vector2d(0, getFieldInfo().yThrowInLineRight);//range check
        } else
        {
          return Vector2d(0, getFieldInfo().yThrowInLineLeft);
        }
      }
      //Own Groundline out -  an der seite wo raus geht
      else if(point.x < getFieldInfo().xPosOwnGroundline)
      {
        Vector2d OwnOutPoint = getFieldInfo().ownLineSegment.point(getFieldInfo().ownLineSegment.intersection(shootLine));
        if(OwnOutPoint.y < 0)
        {
          return Vector2d(getFieldInfo().xThrowInLineOwn, getFieldInfo().yThrowInLineRight);//range check
        } else
        {
          return Vector2d(getFieldInfo().xThrowInLineOwn, getFieldInfo().yThrowInLineLeft);
        }
      }
      //an der linken Seite raus -> ein meter hinter roboter oder wo ins ausgeht ein meter hinter
      else if(point.y > getFieldInfo().yPosLeftSideline )
      {
        Vector2d leftOutPoint = getFieldInfo().leftLineSegment.point(getFieldInfo().leftLineSegment.intersection(shootLine));
        point.x = min(leftOutPoint.x,getRobotPose().translation.x);

        if(point.x-1000 < getFieldInfo().xThrowInLineOwn)
        {
          point.x = getFieldInfo().xThrowInLineOwn;
        } else
        {
          point.x -= 1000;
        }
        return Vector2d(point.x, getFieldInfo().yThrowInLineLeft); //range check
      }
      //an der rechten Seite raus -> ein meter hinter roboter oder wo ins ausgeht ein meter hinter
      else //(point.y < getFieldInfo().yPosRightSideline)
      {
        Vector2d rightOutPoint = getFieldInfo().rightLineSegment.point(getFieldInfo().rightLineSegment.intersection(shootLine));
        point.x = min(rightOutPoint.x,getRobotPose().translation.x);

        if(point.x-1000 < getFieldInfo().xThrowInLineOwn)
        {
        point.x = getFieldInfo().xThrowInLineOwn;
        } else
        {
         point.x -= 1000;
        }
      return Vector2d(point.x, getFieldInfo().yThrowInLineRight);//range check
      }
  }
}

double Simulation::evaluateAction(const Vector2d& a) const{
  Vector2d oppGoal(getFieldInfo().xPosOpponentGoal+200, 0.0);
  Vector2d oppDiff = oppGoal - a;

  double oppValueX = 0.1;
  double oppValueY = 1;
  MODIFY("Simulation:oppValueX", oppValueX);
  MODIFY("Simulation:oppValueY", oppValueY);
  double value_opp = oppValueX*oppDiff.x*oppDiff.x + oppValueY*oppDiff.y*oppDiff.y;

  //Vector2d ownGoal(getFieldInfo().xPosOwnGoal, 0.0);
  //Vector2d ownDiff = ownGoal - a;

  //double ownValueX = 0.01;
  //double ownValueY = 0.1;
  //MODIFY("Simulation:ownValueX", ownValueX);
  //MODIFY("Simulation:ownValueY", ownValueY);
  //double value_own = ownValueX*ownDiff.x*ownDiff.x + ownValueY*ownDiff.y*ownDiff.y;

  //return value_opp - value_own;
  return value_opp;
}

void Simulation::draw_potential_field() const
{
  static const int ySize = 20;
  static const int xSize = 30;
  double yWidth = 0.5*getFieldInfo().yFieldLength/(double)ySize;
  double xWidth = 0.5*getFieldInfo().xFieldLength/(double)xSize;

  FIELD_DRAWING_CONTEXT;
  Color white(0.0,0.0,1.0,0.5); // transparent
  Color black(1.0,0.0,0.0,0.5);

  // create new sample set
  std::vector<double> potential(xSize*ySize);
  int idx = 0;

  for (int x = 0; x < xSize; x++) {
    for (int y = 0; y < ySize; y++)
    {
      Vector2d point(xWidth*(2*x-xSize+1), yWidth*(2*y-ySize+1));
      potential[idx] = evaluateAction(point);
      idx++;
    }
  }

  double maxValue = 0;
  idx = 0;
  for (int x = 0; x < xSize; x++) {
    for (int y = 0; y < ySize; y++)
    {
      maxValue = max(maxValue, potential[idx++]);
    }
  }

  if(maxValue == 0) return;

  idx = 0;
  for (int x = 0; x < xSize; x++) {
    for (int y = 0; y < ySize; y++)
    {
      Vector2d point(xWidth*(2*x-xSize+1), yWidth*(2*y-ySize+1));

      double t = potential[idx++] / maxValue;
      Color color = black*t + white*(1-t);
      PEN(color, 20);
      FILLBOX(point.x - xWidth, point.y - yWidth, point.x+xWidth, point.y+yWidth);
    }
  }
}//end draw_closest_points
<commit_msg>small change in Simulation::categorizePosition<commit_after>/**
* @file Simulation.cpp
* @author Benjamin Schlotter
* Implementation of class Simulation
*/

#include "Simulation.h"

using namespace naoth;
using namespace std;

Simulation::Simulation()
{
  DEBUG_REQUEST_REGISTER("Simulation:draw_one_action_point:global","draw_one_action_point:global", false);
  DEBUG_REQUEST_REGISTER("Simulation:draw_ball","draw_ball", false);
  DEBUG_REQUEST_REGISTER("Simulation:ActionTarget","ActionTarget", false);
  DEBUG_REQUEST_REGISTER("Simulation:draw_best_action","best action",false);
  //DEBUG_REQUEST_REGISTER("Simulation:draw_pessimistic_best_action","best pessimistic action",false);
  DEBUG_REQUEST_REGISTER("Simulation:GoalLinePreview","GoalLinePreview",false);
  DEBUG_REQUEST_REGISTER("Simulation:draw_potential_field","Draw Potential Field",false);
  DEBUG_REQUEST_REGISTER("Simulation:use_Parameters","use_Parameters",false);

  getDebugParameterList().add(&theParameters);

  //actionRingBuffer.resize(ActionModel::numOfActions);
  //calculate the actions
  action_local.reserve(KickActionModel::numOfActions);

  action_local.push_back(Action(KickActionModel::none, Vector2d()));
  action_local.push_back(Action(KickActionModel::kick_long, Vector2d(theParameters.action_long_kick_distance, 0))); // long
  action_local.push_back(Action(KickActionModel::kick_short, Vector2d(theParameters.action_short_kick_distance, 0))); // short
  action_local.push_back(Action(KickActionModel::sidekick_right, Vector2d(0, -theParameters.action_sidekick_distance))); // right
  action_local.push_back(Action(KickActionModel::sidekick_left, Vector2d(0, theParameters.action_sidekick_distance))); // left
}

Simulation::~Simulation(){}

void Simulation::execute()
{
  DEBUG_REQUEST("Simulation:use_Parameters",
  action_local.clear();
  action_local.reserve(KickActionModel::numOfActions);

  action_local.push_back(Action(KickActionModel::none, Vector2d()));
  action_local.push_back(Action(KickActionModel::kick_long, Vector2d(theParameters.action_long_kick_distance, 0))); // long
  action_local.push_back(Action(KickActionModel::kick_short, Vector2d(theParameters.action_short_kick_distance, 0))); // short
  action_local.push_back(Action(KickActionModel::sidekick_right, Vector2d(0, -theParameters.action_sidekick_distance))); // right
  action_local.push_back(Action(KickActionModel::sidekick_left, Vector2d(0, theParameters.action_sidekick_distance))); // left
  );

  if(!getBallModel().valid || getFrameInfo().getTimeInSeconds() >= getBallModel().frameInfoWhenBallWasSeen.getTimeInSeconds()+1)
  {
    return;
  }
  else
  {
    int best_action = 0;

    for(size_t i=0; i<action_local.size(); i++)
    {
      // physics simulator
      std::vector<Vector2d> ballPositionResults;
      for(size_t j=0; j<30; j++)
      {
        const Vector2d& ballRelativePreview = getBallModel().positionPreview;
        Vector2d ballPositionResult = action_local[i].predict(ballRelativePreview, theParameters.distance_variance, theParameters.angle_variance);
        ballPositionResults.push_back(ballPositionResult);
      }

      // categorize positions
      std::vector<CategorizedBallPosition> categorizedBallPositionResults;
      for(std::vector<Vector2d>::iterator ballPosition = ballPositionResults.begin(); ballPosition != ballPositionResults.end(); ballPosition++)
      {
        BallPositionCategory category = this->categorizePosition(*ballPosition);
        CategorizedBallPosition categorizedBallPosition = CategorizedBallPosition(*ballPosition, category);
        categorizedBallPositionResults.push_back(categorizedBallPosition);
      }
    }

    getKickActionModel().myAction = action_local[best_action].id();

    DEBUG_REQUEST("Simulation:draw_best_action",
    {
      FIELD_DRAWING_CONTEXT;
      PEN("FF69B4", 7);
      Vector2d actionGlobal = action_local[best_action].target;
      FILLOVAL(actionGlobal.x, actionGlobal.y, 50,50);
    });

//  DEBUG_REQUEST("Simulation:draw_potential_field",
//     draw_potential_field();
//  );

  }
}//end execute

Simulation::BallPositionCategory Simulation::categorizePosition(const Vector2d& globalPoint) const
{
  Vector2d point = globalPoint;

  //Schusslinie
  Math::LineSegment shootLine(getBallModel().positionPreview, globalPoint);

  BallPositionCategory cat = INFIELD;
  if(getFieldInfo().fieldRect.inside(point)){
    cat = INFIELD;
  } else
  {
    //Opponent Groundline Out - Ball einen Meter hinter Roboter mind ansto hhe. jeweils seite wo ins ausgeht
    if(point.x > getFieldInfo().xPosOpponentGroundline)
    {
      cat = OPPOUT;
    }
    //Own Groundline out -  an der seite wo raus geht
    else if(point.x < getFieldInfo().xPosOwnGroundline)
    {
      cat = OWNOUT;
    }
    //an der linken Seite raus -> ein meter hinter roboter oder wo ins ausgeht ein meter hinter
    else if(point.y > getFieldInfo().yPosLeftSideline )
    {
      cat = LEFTOUT;
    }
    //an der rechten Seite raus -> ein meter hinter roboter oder wo ins ausgeht ein meter hinter
    else if(point.y < getFieldInfo().yPosRightSideline)
    {
      cat = RIGHTOUT;
    }
  }
  return cat;
}

Vector2d Simulation::calculateOneAction(const Action& action) const
{
  // STEP 1: predict the action outcome
  const Vector2d& ballRelativePreview = getBallModel().positionPreview;

  DEBUG_REQUEST("Simulation:draw_ball",
    FIELD_DRAWING_CONTEXT;
    PEN("FF0000", 1);
    Vector2d ball = getRobotPose() * getBallModel().positionPreview;
    CIRCLE( ball.x, ball.y, 50);
  );

  Vector2d result = action.predict(ballRelativePreview, theParameters.distance_variance, theParameters.angle_variance);

  DEBUG_REQUEST("Simulation:ActionTarget",
    FIELD_DRAWING_CONTEXT;
    PEN("0000FF", 1);
    Vector2d ball = getRobotPose() * result;
    CIRCLE( ball.x, ball.y, 50);
  );

  // STEP 2: calculate the goal line
  GoalModel::Goal oppGoalModel = getSelfLocGoalModel().getOppGoal(getCompassDirection(), getFieldInfo());
  Vector2d oppGoalPostLeftPreview = getMotionStatus().plannedMotion.hip / oppGoalModel.leftPost;
  Vector2d oppGoalPostRightPreview = getMotionStatus().plannedMotion.hip / oppGoalModel.rightPost;

  //the endpoints of our line are a shortened version of the goal line
  Vector2d goalDir = (oppGoalPostRightPreview - oppGoalPostLeftPreview).normalize();
  Vector2d leftEndpoint = oppGoalPostLeftPreview + goalDir*(getFieldInfo().goalpostRadius + getFieldInfo().ballRadius);
  Vector2d rightEndpoint = oppGoalPostRightPreview - goalDir*(getFieldInfo().goalpostRadius + getFieldInfo().ballRadius);

  // this is the goalline we are shooting for
  Math::LineSegment goalLinePreview(leftEndpoint, rightEndpoint);

  // note: the drawing is global
  DEBUG_REQUEST("Simulation:GoalLinePreview",
    FIELD_DRAWING_CONTEXT;
    PEN("000000", 1);
    Vector2d globalLeft = getRobotPose() * leftEndpoint;
    Vector2d globalRight = getRobotPose() * rightEndpoint;
    LINE(globalLeft.x,globalLeft.y,globalRight.x,globalRight.y);
  );

  // STEP 3: estimate external factors (shooting a goal, ball moved by referee)
  //Math::LineSegment shootLine(ballRelativePreview, outsideField(lonely_action.target));//hmm
  Math::LineSegment shootLine(ballRelativePreview, result);

  Vector2d resultingBallPosition;

  if(shootLine.intersect(goalLinePreview) && goalLinePreview.intersect(shootLine)) {
    resultingBallPosition = Vector2d(getFieldInfo().xPosOpponentGoal+200, 0.0);
  } else {
    resultingBallPosition = outsideField(getRobotPose() * result);
  }

  return resultingBallPosition;
}

  //correction of distance in percentage, angle in degrees
  Vector2d Simulation::Action::predict(const Vector2d& ball, double distance_variance, double angle_variance) const
  {
  double random_length = 2.0*Math::random()-1.0;
  double random_angle = 2.0*Math::random()-1.0;

  Vector2d noisyAction = actionVector + actionVector*(distance_variance*random_length);
  noisyAction.rotate(angle_variance*random_angle);

  return ball + noisyAction;
  }

//calcualte according to the rules, without the roboter position, the ball position
//if it goes outside the field
Vector2d Simulation::outsideField(const Vector2d& globalPoint) const
{
  Vector2d point = globalPoint;

  //Schusslinie
  Math::LineSegment shootLine(getBallModel().positionPreview, globalPoint);

  if(getFieldInfo().fieldRect.inside(point)){
    return point;
  }
  else
      //Nach Prioritten geordnet - zuerst die Regeln mit dem mglichst schlimmsten Resultat
  {   //Opponent Groundline Out - Ball einen Meter hinter Roboter mind ansto hhe. jeweils seite wo ins ausgeht
      if(point.x > getFieldInfo().xPosOpponentGroundline)
      {
        Vector2d OppOutPoint = getFieldInfo().oppLineSegment.point(getFieldInfo().oppLineSegment.intersection(shootLine));
        if(OppOutPoint.y < 0)
        {
          return Vector2d(0, getFieldInfo().yThrowInLineRight);//range check
        } else
        {
          return Vector2d(0, getFieldInfo().yThrowInLineLeft);
        }
      }
      //Own Groundline out -  an der seite wo raus geht
      else if(point.x < getFieldInfo().xPosOwnGroundline)
      {
        Vector2d OwnOutPoint = getFieldInfo().ownLineSegment.point(getFieldInfo().ownLineSegment.intersection(shootLine));
        if(OwnOutPoint.y < 0)
        {
          return Vector2d(getFieldInfo().xThrowInLineOwn, getFieldInfo().yThrowInLineRight);//range check
        } else
        {
          return Vector2d(getFieldInfo().xThrowInLineOwn, getFieldInfo().yThrowInLineLeft);
        }
      }
      //an der linken Seite raus -> ein meter hinter roboter oder wo ins ausgeht ein meter hinter
      else if(point.y > getFieldInfo().yPosLeftSideline )
      {
        Vector2d leftOutPoint = getFieldInfo().leftLineSegment.point(getFieldInfo().leftLineSegment.intersection(shootLine));
        point.x = min(leftOutPoint.x,getRobotPose().translation.x);

        if(point.x-1000 < getFieldInfo().xThrowInLineOwn)
        {
          point.x = getFieldInfo().xThrowInLineOwn;
        } else
        {
          point.x -= 1000;
        }
        return Vector2d(point.x, getFieldInfo().yThrowInLineLeft); //range check
      }
      //an der rechten Seite raus -> ein meter hinter roboter oder wo ins ausgeht ein meter hinter
      else //(point.y < getFieldInfo().yPosRightSideline)
      {
        Vector2d rightOutPoint = getFieldInfo().rightLineSegment.point(getFieldInfo().rightLineSegment.intersection(shootLine));
        point.x = min(rightOutPoint.x,getRobotPose().translation.x);

        if(point.x-1000 < getFieldInfo().xThrowInLineOwn)
        {
        point.x = getFieldInfo().xThrowInLineOwn;
        } else
        {
         point.x -= 1000;
        }
      return Vector2d(point.x, getFieldInfo().yThrowInLineRight);//range check
      }
  }
}

double Simulation::evaluateAction(const Vector2d& a) const{
  Vector2d oppGoal(getFieldInfo().xPosOpponentGoal+200, 0.0);
  Vector2d oppDiff = oppGoal - a;

  double oppValueX = 0.1;
  double oppValueY = 1;
  MODIFY("Simulation:oppValueX", oppValueX);
  MODIFY("Simulation:oppValueY", oppValueY);
  double value_opp = oppValueX*oppDiff.x*oppDiff.x + oppValueY*oppDiff.y*oppDiff.y;

  //Vector2d ownGoal(getFieldInfo().xPosOwnGoal, 0.0);
  //Vector2d ownDiff = ownGoal - a;

  //double ownValueX = 0.01;
  //double ownValueY = 0.1;
  //MODIFY("Simulation:ownValueX", ownValueX);
  //MODIFY("Simulation:ownValueY", ownValueY);
  //double value_own = ownValueX*ownDiff.x*ownDiff.x + ownValueY*ownDiff.y*ownDiff.y;

  //return value_opp - value_own;
  return value_opp;
}

void Simulation::draw_potential_field() const
{
  static const int ySize = 20;
  static const int xSize = 30;
  double yWidth = 0.5*getFieldInfo().yFieldLength/(double)ySize;
  double xWidth = 0.5*getFieldInfo().xFieldLength/(double)xSize;

  FIELD_DRAWING_CONTEXT;
  Color white(0.0,0.0,1.0,0.5); // transparent
  Color black(1.0,0.0,0.0,0.5);

  // create new sample set
  std::vector<double> potential(xSize*ySize);
  int idx = 0;

  for (int x = 0; x < xSize; x++) {
    for (int y = 0; y < ySize; y++)
    {
      Vector2d point(xWidth*(2*x-xSize+1), yWidth*(2*y-ySize+1));
      potential[idx] = evaluateAction(point);
      idx++;
    }
  }

  double maxValue = 0;
  idx = 0;
  for (int x = 0; x < xSize; x++) {
    for (int y = 0; y < ySize; y++)
    {
      maxValue = max(maxValue, potential[idx++]);
    }
  }

  if(maxValue == 0) return;

  idx = 0;
  for (int x = 0; x < xSize; x++) {
    for (int y = 0; y < ySize; y++)
    {
      Vector2d point(xWidth*(2*x-xSize+1), yWidth*(2*y-ySize+1));

      double t = potential[idx++] / maxValue;
      Color color = black*t + white*(1-t);
      PEN(color, 20);
      FILLBOX(point.x - xWidth, point.y - yWidth, point.x+xWidth, point.y+yWidth);
    }
  }
}//end draw_closest_points
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <chrono>
#include <thread>

#include <gtest/gtest.h>

#include <react/renderer/telemetry/TransactionTelemetry.h>
#include <react/utils/Telemetry.h>

using namespace facebook::react;

template <typename ClockT>
void sleep(double durationInSeconds) {
  auto timepoint = ClockT::now() +
      std::chrono::milliseconds((long long)(durationInSeconds * 1000));
  while (ClockT::now() < timepoint) {
  }
}

TEST(TransactionTelemetryTest, timepoints) {
  auto threshold = int64_t{70};

  auto timepointA = telemetryTimePointNow();
  sleep<TelemetryClock>(0.1);
  auto timepointB = telemetryTimePointNow();

  auto duration = telemetryDurationToMilliseconds(timepointB - timepointA);

  EXPECT_NEAR(duration, 100, threshold);
}

TEST(TransactionTelemetryTest, normalUseCase) {
  auto threshold = int64_t{70};
  auto telemetry = TransactionTelemetry{};

  telemetry.setAsThreadLocal();

  telemetry.willCommit();
  sleep<TelemetryClock>(0.1);
  telemetry.willLayout();
  sleep<TelemetryClock>(0.2);

  TransactionTelemetry::threadLocalTelemetry()->willMeasureText();
  sleep<TelemetryClock>(0.1);
  TransactionTelemetry::threadLocalTelemetry()->didMeasureText();

  TransactionTelemetry::threadLocalTelemetry()->willMeasureText();
  sleep<TelemetryClock>(0.2);
  TransactionTelemetry::threadLocalTelemetry()->didMeasureText();

  TransactionTelemetry::threadLocalTelemetry()->willMeasureText();
  sleep<TelemetryClock>(0.3);
  TransactionTelemetry::threadLocalTelemetry()->didMeasureText();

  telemetry.didLayout();
  sleep<TelemetryClock>(0.1);
  telemetry.didCommit();

  telemetry.setRevisionNumber(42);

  telemetry.unsetAsThreadLocal();

  sleep<TelemetryClock>(0.3);

  telemetry.willMount();
  sleep<TelemetryClock>(0.1);
  telemetry.didMount();

  auto commitDuration = telemetryDurationToMilliseconds(
      telemetry.getCommitEndTime() - telemetry.getCommitStartTime());
  auto layoutDuration = telemetryDurationToMilliseconds(
      telemetry.getLayoutEndTime() - telemetry.getLayoutStartTime());
  auto mountDuration = telemetryDurationToMilliseconds(
      telemetry.getMountEndTime() - telemetry.getMountStartTime());

  EXPECT_NEAR(commitDuration, 1000, threshold);
  EXPECT_NEAR(layoutDuration, 800, threshold);
  EXPECT_NEAR(mountDuration, 100, threshold);

  EXPECT_EQ(telemetry.getNumberOfTextMeasurements(), 3);
  EXPECT_NEAR(
      telemetryDurationToMilliseconds(telemetry.getTextMeasureTime()),
      600,
      threshold);
  EXPECT_EQ(telemetry.getRevisionNumber(), 42);
}

TEST(TransactionTelemetryTest, abnormalUseCases) {
  // Calling `did` before `will` should crash.
  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.didDiff();
      },
      "diffStartTime_");

  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.didCommit();
      },
      "commitStartTime_");

  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.didMount();
      },
      "mountStartTime_");

  // Getting `start` *or* `end` timepoints before a pair of `will` and `did`
  // should crash.
  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.willCommit();
        telemetry.getCommitStartTime();
      },
      "commitEndTime_");

  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.willCommit();
        telemetry.getCommitEndTime();
      },
      "commitEndTime_");
}
<commit_msg>Use mock clock<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include <chrono>
#include <thread>

#include <gtest/gtest.h>

#include <react/renderer/telemetry/TransactionTelemetry.h>
#include <react/utils/Telemetry.h>

using namespace facebook::react;

class MockClock {
 public:
  typedef std::chrono::
      time_point<std::chrono::steady_clock, std::chrono::nanoseconds>
          time_point;

  static time_point now() noexcept {
    return time_;
  }

  template <typename TDuration>
  static void advance_by(const TDuration duration) {
    time_ += duration;
  }

 private:
  static time_point time_;
};

MockClock::time_point MockClock::time_ = {};

/**
 * Ensures that the at least the specified time passes on a real clock.
 * Why at least? Because operating systems provide no guarantee that our thread
 * gets processing time after the specified time. What about using a busywait?
 * Busywait are also affected by the non-deterministic OS process scheduling.
 * The OS might decide right before the specified time elapsed to schedule
 * another thread/process, with the result that more time passes in reality than
 * the caller intended. Prefer the `MockClock` and only use this function to
 * verify that at least the specifid time has passed but wihtout making exact
 * verifications.
 */
static void sleepAtLeast(double durationInSeconds) {
  std::this_thread::sleep_for(
      std::chrono::milliseconds((long long)(durationInSeconds * 1000)));
}

TEST(TransactionTelemetryTest, timepoints) {
  auto timepointA = telemetryTimePointNow();
  sleepAtLeast(0.1);
  auto timepointB = telemetryTimePointNow();

  auto duration = telemetryDurationToMilliseconds(timepointB - timepointA);

  EXPECT_GE(duration, 100);
}

TEST(TransactionTelemetryTest, normalUseCase) {
  auto telemetry = TransactionTelemetry{[]() { return MockClock::now(); }};

  telemetry.setAsThreadLocal();

  telemetry.willCommit();
  MockClock::advance_by(std::chrono::milliseconds(100));
  telemetry.willLayout();
  MockClock::advance_by(std::chrono::milliseconds(200));

  TransactionTelemetry::threadLocalTelemetry()->willMeasureText();
  MockClock::advance_by(std::chrono::milliseconds(100));
  TransactionTelemetry::threadLocalTelemetry()->didMeasureText();

  TransactionTelemetry::threadLocalTelemetry()->willMeasureText();
  MockClock::advance_by(std::chrono::milliseconds(200));
  TransactionTelemetry::threadLocalTelemetry()->didMeasureText();

  TransactionTelemetry::threadLocalTelemetry()->willMeasureText();
  MockClock::advance_by(std::chrono::milliseconds(300));
  TransactionTelemetry::threadLocalTelemetry()->didMeasureText();

  telemetry.didLayout();
  MockClock::advance_by(std::chrono::milliseconds(100));
  telemetry.didCommit();

  telemetry.setRevisionNumber(42);

  telemetry.unsetAsThreadLocal();

  MockClock::advance_by(std::chrono::milliseconds(300));

  telemetry.willMount();
  MockClock::advance_by(std::chrono::milliseconds(100));
  telemetry.didMount();

  auto commitDuration = telemetryDurationToMilliseconds(
      telemetry.getCommitEndTime() - telemetry.getCommitStartTime());
  auto layoutDuration = telemetryDurationToMilliseconds(
      telemetry.getLayoutEndTime() - telemetry.getLayoutStartTime());
  auto mountDuration = telemetryDurationToMilliseconds(
      telemetry.getMountEndTime() - telemetry.getMountStartTime());

  EXPECT_EQ(commitDuration, 1000);
  EXPECT_EQ(layoutDuration, 800);
  EXPECT_EQ(mountDuration, 100);

  EXPECT_EQ(telemetry.getNumberOfTextMeasurements(), 3);
  EXPECT_EQ(
      telemetryDurationToMilliseconds(telemetry.getTextMeasureTime()), 600);
  EXPECT_EQ(telemetry.getRevisionNumber(), 42);
}

TEST(TransactionTelemetryTest, defaultImplementation) {
  auto telemetry = TransactionTelemetry{};

  telemetry.setAsThreadLocal();

  telemetry.willCommit();
  sleepAtLeast(0.1);
  telemetry.willLayout();
  sleepAtLeast(0.2);

  TransactionTelemetry::threadLocalTelemetry()->willMeasureText();
  sleepAtLeast(0.1);
  TransactionTelemetry::threadLocalTelemetry()->didMeasureText();

  telemetry.didLayout();
  sleepAtLeast(0.1);
  telemetry.didCommit();

  telemetry.unsetAsThreadLocal();

  telemetry.willMount();
  sleepAtLeast(0.1);
  telemetry.didMount();

  auto commitDuration = telemetryDurationToMilliseconds(
      telemetry.getCommitEndTime() - telemetry.getCommitStartTime());
  auto layoutDuration = telemetryDurationToMilliseconds(
      telemetry.getLayoutEndTime() - telemetry.getLayoutStartTime());
  auto mountDuration = telemetryDurationToMilliseconds(
      telemetry.getMountEndTime() - telemetry.getMountStartTime());

  EXPECT_GE(commitDuration, 500);
  EXPECT_GE(layoutDuration, 300);
  EXPECT_GE(mountDuration, 100);
}

TEST(TransactionTelemetryTest, abnormalUseCases) {
  // Calling `did` before `will` should crash.
  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.didDiff();
      },
      "diffStartTime_");

  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.didCommit();
      },
      "commitStartTime_");

  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.didMount();
      },
      "mountStartTime_");

  // Getting `start` *or* `end` timepoints before a pair of `will` and `did`
  // should crash.
  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.willCommit();
        telemetry.getCommitStartTime();
      },
      "commitEndTime_");

  EXPECT_DEATH_IF_SUPPORTED(
      {
        auto telemetry = TransactionTelemetry{};
        telemetry.willCommit();
        telemetry.getCommitEndTime();
      },
      "commitEndTime_");
}
<|endoftext|>


<commit_before>/*
 * Copyright 2007-2020 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <boost/intrusive/list.hpp>

/*8
 * A job that shall be executed in a worker thread.
 */
class ThreadJob
	: public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
public:
	enum class State {
		/**
		 * The job is not in any queue.
		 */
		INITIAL,

		/**
		 * The job has been added to the queue, but is not being worked on
		 * yet.
		 */
		WAITING,

		/**
		 * The job is being performed via run().
		 */
		BUSY,

		/**
		 * The job has finished, but the done() method has not been
		 * invoked yet.
		 */
		DONE,
	};

	State state = State::INITIAL;

	/**
	 * Shall this job be enqueued again instead of invoking its done()
	 * method?
	 */
	bool again = false;

	/**
	 * Is this job currently idle, i.e. not being worked on by a
	 * worker thread?  This method may be called only from the main
	 * thread.  A "true" return value guarantees that no worker thread
	 * is and will be working on it, and its internal data structures
	 * may be accessed without mutex protection.  Use this method with
	 * caution.
	 */
	bool IsIdle() const {
		return state == State::INITIAL;
	}

	virtual void Run() noexcept = 0;
	virtual void Done() noexcept = 0;
};
<commit_msg>thread/Job: add `noexcept`<commit_after>/*
 * Copyright 2007-2020 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <boost/intrusive/list.hpp>

/*8
 * A job that shall be executed in a worker thread.
 */
class ThreadJob
	: public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
public:
	enum class State {
		/**
		 * The job is not in any queue.
		 */
		INITIAL,

		/**
		 * The job has been added to the queue, but is not being worked on
		 * yet.
		 */
		WAITING,

		/**
		 * The job is being performed via run().
		 */
		BUSY,

		/**
		 * The job has finished, but the done() method has not been
		 * invoked yet.
		 */
		DONE,
	};

	State state = State::INITIAL;

	/**
	 * Shall this job be enqueued again instead of invoking its done()
	 * method?
	 */
	bool again = false;

	/**
	 * Is this job currently idle, i.e. not being worked on by a
	 * worker thread?  This method may be called only from the main
	 * thread.  A "true" return value guarantees that no worker thread
	 * is and will be working on it, and its internal data structures
	 * may be accessed without mutex protection.  Use this method with
	 * caution.
	 */
	bool IsIdle() const noexcept {
		return state == State::INITIAL;
	}

	virtual void Run() noexcept = 0;
	virtual void Done() noexcept = 0;
};
<|endoftext|>


<commit_before>class Solution {
public:
    vector<string> generatePossibleNextMoves(string s) {
        vector<string> ans;
        const int n = s.length();
        for (int i = 1; i < n; ++i) {
            string next = s;
            if (s[i] == '+' && s[i - 1] == '+') {
                next[i] = '-';
                next[i - 1] = '-';
                ans.push_back(next);
            }
        }
        return ans;
    }
};<commit_msg>added solutions<commit_after>class Solution {
public:
    vector<string> generatePossibleNextMoves(string s) {
        vector<string> result;
        int len = (int) s.length();
        for (int i = 0; i < len - 1; ++i) {
            if (s[i] == '+' && s[i + 1] == '+') {
                result.push_back(s);
                result[result.size() - 1][i] = '-';
                result[result.size() - 1][i + 1] = '-';
            }
        }
        return result;
    }
};<|endoftext|>


<commit_before>/*
 * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#include <boost/algorithm/string/replace.hpp>
#include <boost/range/algorithm.hpp>
#include <fstream>
#include <stdexcept>
#include <vector>
#include <votca/tools/lexical_cast.h>
#include <votca/tools/table.h>
#include <votca/tools/tokenizer.h>

namespace votca {
namespace tools {

using namespace boost;
using namespace std;

void Table::resize(int N) {
  _x.conservativeResize(N);
  _y.conservativeResize(N);
  _flags.resize(N);
  if (_has_yerr) {
    _yerr.conservativeResize(N);
  }
}

void Table::Load(string filename) {
  ifstream in;
  in.open(filename.c_str());
  if (!in) throw runtime_error(string("error, cannot open file ") + filename);

  setErrorDetails("file " + filename);
  in >> *this;
  in.close();
}

void Table::Save(string filename) const {
  ofstream out;
  out.open(filename.c_str());
  if (!out) throw runtime_error(string("error, cannot open file ") + filename);

  if (_has_comment) {
    string str = "# " + _comment_line;
    boost::replace_all(str, "\n", "\n# ");
    boost::replace_all(str, "\\n", "\n# ");
    out << str << endl;
  }
  out << (*this);

  out.close();
}

void Table::clear(void) {
  _x.resize(0);
  _y.resize(0);
  _flags.resize(0);
  _yerr.resize(0);
}

double Table::getMaxY() const { return _y.maxCoeff(); }

double Table::getMinY() const { return _y.minCoeff(); }

double Table::getMaxX() const { return _x.maxCoeff(); }

double Table::getMinX() const { return _x.minCoeff(); }

// TODO: this functon is weired, reading occours twice, cleanup!!
// TODO: modify function to work properly, when _has_yerr is true
istream &operator>>(istream &in, Table &t) {
  size_t N = 0;
  bool bHasN = false;
  string line;
  int line_number = 0;
  t.clear();

  // read till the first data line
  while (getline(in, line)) {
    line_number++;
    string conversion_error = t.getErrorDetails() + ", line " +
                              boost::lexical_cast<string>(line_number);

    // remove comments and xmgrace stuff
    line = line.substr(0, line.find("#"));
    line = line.substr(0, line.find("@"));

    // tokenize string and put it to vector
    Tokenizer tok(line, " \t");
    vector<string> tokens;
    tok.ToVector(tokens);

    // skip empty lines
    if (tokens.size() == 0) continue;

    // if first line is only 1 token, it's the size
    if (tokens.size() == 1) {
      N = lexical_cast<int>(tokens[0], conversion_error);
      bHasN = true;
    } else if (tokens.size() == 2) {
      // it's the first data line with 2 or 3 entries
      t.push_back(std::stod(tokens[0]), std::stod(tokens[1]), 'i');
    } else if (tokens.size() > 2) {
      char flag = 'i';
      string sflag = tokens.back();
      if (sflag == "i" || sflag == "o" || sflag == "u") flag = sflag.c_str()[0];
      t.push_back(std::stod(tokens[0]), std::stod(tokens[1]), flag);
    } else {
      throw runtime_error("error, wrong table format");
    }
  }

  // read the rest
  while (getline(in, line)) {
    line_number++;
    string conversion_error = t.getErrorDetails() + ", line " +
                              boost::lexical_cast<string>(line_number);

    // remove comments and xmgrace stuff
    line = line.substr(0, line.find("#"));
    line = line.substr(0, line.find("@"));

    // tokenize string and put it to vector
    Tokenizer tok(line, " \t");
    vector<string> tokens;
    tok.ToVector(tokens);

    // skip empty lines
    if (tokens.size() == 0) continue;

    // it's a data line
    if (tokens.size() == 2) {
      t.push_back(std::stod(tokens[0]), std::stod(tokens[1]), 'i');
    } else if (tokens.size() > 2) {
      char flag = 'i';
      if (tokens[2] == "i" || tokens[2] == "o" || tokens[2] == "u")
        flag = tokens[2].c_str()[0];
      t.push_back(std::stod(tokens[0]), std::stod(tokens[1]), flag);
    } else {
      // otherwise error
      throw runtime_error("error, wrong table format");
    }
    // was size given and did we read N values?
    if (bHasN) {
      if (--N == 0) break;
    }
  }

  return in;
}

void Table::GenerateGridSpacing(double min, double max, double spacing) {
  int n = floor((max - min) / spacing + 1.000000001);
  resize(n);
  int i = 0;
  for (double x = min; i < n; x += spacing, ++i) _x[i] = x;
}

void Table::Smooth(int Nsmooth) {
  while (Nsmooth-- > 0)
    for (int i = 1; i < size() - 1; ++i) {
      _y[i] = 0.25 * (_y[i - 1] + 2 * _y[i] + _y[i + 1]);
    }
}
}  // namespace tools
}  // namespace votca
<commit_msg>remove c_str()<commit_after>/*
 * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#include <boost/algorithm/string/replace.hpp>
#include <boost/range/algorithm.hpp>
#include <fstream>
#include <stdexcept>
#include <vector>
#include <votca/tools/lexical_cast.h>
#include <votca/tools/table.h>
#include <votca/tools/tokenizer.h>

namespace votca {
namespace tools {

using namespace boost;
using namespace std;

void Table::resize(int N) {
  _x.conservativeResize(N);
  _y.conservativeResize(N);
  _flags.resize(N);
  if (_has_yerr) {
    _yerr.conservativeResize(N);
  }
}

void Table::Load(string filename) {
  ifstream in;
  in.open(filename.c_str());
  if (!in) throw runtime_error(string("error, cannot open file ") + filename);

  setErrorDetails("file " + filename);
  in >> *this;
  in.close();
}

void Table::Save(string filename) const {
  ofstream out;
  out.open(filename);
  if (!out) throw runtime_error(string("error, cannot open file ") + filename);

  if (_has_comment) {
    string str = "# " + _comment_line;
    boost::replace_all(str, "\n", "\n# ");
    boost::replace_all(str, "\\n", "\n# ");
    out << str << endl;
  }
  out << (*this);

  out.close();
}

void Table::clear(void) {
  _x.resize(0);
  _y.resize(0);
  _flags.resize(0);
  _yerr.resize(0);
}

double Table::getMaxY() const { return _y.maxCoeff(); }

double Table::getMinY() const { return _y.minCoeff(); }

double Table::getMaxX() const { return _x.maxCoeff(); }

double Table::getMinX() const { return _x.minCoeff(); }

// TODO: this functon is weired, reading occours twice, cleanup!!
// TODO: modify function to work properly, when _has_yerr is true
istream &operator>>(istream &in, Table &t) {
  size_t N = 0;
  bool bHasN = false;
  string line;
  int line_number = 0;
  t.clear();

  // read till the first data line
  while (getline(in, line)) {
    line_number++;
    string conversion_error = t.getErrorDetails() + ", line " +
                              boost::lexical_cast<string>(line_number);

    // remove comments and xmgrace stuff
    line = line.substr(0, line.find("#"));
    line = line.substr(0, line.find("@"));

    // tokenize string and put it to vector
    Tokenizer tok(line, " \t");
    vector<string> tokens;
    tok.ToVector(tokens);

    // skip empty lines
    if (tokens.size() == 0) continue;

    // if first line is only 1 token, it's the size
    if (tokens.size() == 1) {
      N = lexical_cast<int>(tokens[0], conversion_error);
      bHasN = true;
    } else if (tokens.size() == 2) {
      // it's the first data line with 2 or 3 entries
      t.push_back(std::stod(tokens[0]), std::stod(tokens[1]), 'i');
    } else if (tokens.size() > 2) {
      char flag = 'i';
      string sflag = tokens.back();
      if (sflag == "i" || sflag == "o" || sflag == "u") flag = sflag.c_str()[0];
      t.push_back(std::stod(tokens[0]), std::stod(tokens[1]), flag);
    } else {
      throw runtime_error("error, wrong table format");
    }
  }

  // read the rest
  while (getline(in, line)) {
    line_number++;
    string conversion_error = t.getErrorDetails() + ", line " +
                              boost::lexical_cast<string>(line_number);

    // remove comments and xmgrace stuff
    line = line.substr(0, line.find("#"));
    line = line.substr(0, line.find("@"));

    // tokenize string and put it to vector
    Tokenizer tok(line, " \t");
    vector<string> tokens;
    tok.ToVector(tokens);

    // skip empty lines
    if (tokens.size() == 0) continue;

    // it's a data line
    if (tokens.size() == 2) {
      t.push_back(std::stod(tokens[0]), std::stod(tokens[1]), 'i');
    } else if (tokens.size() > 2) {
      char flag = 'i';
      if (tokens[2] == "i" || tokens[2] == "o" || tokens[2] == "u")
        flag = tokens[2].c_str()[0];
      t.push_back(std::stod(tokens[0]), std::stod(tokens[1]), flag);
    } else {
      // otherwise error
      throw runtime_error("error, wrong table format");
    }
    // was size given and did we read N values?
    if (bHasN) {
      if (--N == 0) break;
    }
  }

  return in;
}

void Table::GenerateGridSpacing(double min, double max, double spacing) {
  int n = floor((max - min) / spacing + 1.000000001);
  resize(n);
  int i = 0;
  for (double x = min; i < n; x += spacing, ++i) _x[i] = x;
}

void Table::Smooth(int Nsmooth) {
  while (Nsmooth-- > 0)
    for (int i = 1; i < size() - 1; ++i) {
      _y[i] = 0.25 * (_y[i - 1] + 2 * _y[i] + _y[i + 1]);
    }
}
}  // namespace tools
}  // namespace votca
<|endoftext|>


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

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXREPLACE_HPP_
#include <com/sun/star/container/XIndexReplace.hpp>
#endif
#ifndef _COM_SUN_STAR_STYLE_NUMBERINGTYPE_HPP_
#include <com/sun/star/style/NumberingType.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_
#include <com/sun/star/container/XNamed.hpp>
#endif

#ifndef _XMLOFF_XMLTEXTNUMRULEINFO_HXX
#include "XMLTextNumRuleInfo.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::style;

XMLTextNumRuleInfo::XMLTextNumRuleInfo() :
    sNumberingRules(RTL_CONSTASCII_USTRINGPARAM("NumberingRules")),
    sNumberingLevel(RTL_CONSTASCII_USTRINGPARAM("NumberingLevel")),
    sNumberingStartValue(RTL_CONSTASCII_USTRINGPARAM("NumberingStartValue")),
    sParaIsNumberingRestart(RTL_CONSTASCII_USTRINGPARAM("ParaIsNumberingRestart")),
    sNumberingType(RTL_CONSTASCII_USTRINGPARAM("NumberingType")),
    sIsNumbering(RTL_CONSTASCII_USTRINGPARAM("IsNumbering")),
    sNumberingIsNumber(RTL_CONSTASCII_USTRINGPARAM("NumberingIsNumber")),
    sNumberingIsOutline(RTL_CONSTASCII_USTRINGPARAM("NumberingIsOutline"))
{
    Reset();
}

void XMLTextNumRuleInfo::Set(
        const ::com::sun::star::uno::Reference <
            ::com::sun::star::text::XTextContent > & xTextContent )
{
    Reset();

    Reference< XPropertySet > xPropSet( xTextContent, UNO_QUERY );
    Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();

    Any aAny;

    // check if this paragraph supports a numbering
    if( !xPropSetInfo->hasPropertyByName( sNumberingLevel ) )
        return;

    if( xPropSetInfo->hasPropertyByName( sNumberingRules ) )
    {
        aAny = xPropSet->getPropertyValue( sNumberingRules );
        aAny >>= xNumRules;
    }

    BOOL bIsOutline = FALSE;

    Reference<XPropertySet> xNumRulesProps(xNumRules, UNO_QUERY);
    if (xNumRulesProps.is() &&
        xNumRulesProps->getPropertySetInfo()->
        hasPropertyByName( sNumberingIsOutline ) )
    {
        aAny = xNumRulesProps->getPropertyValue( sNumberingIsOutline );
        bIsOutline = *(sal_Bool*)aAny.getValue();
    }

    if( xNumRules.is() && !bIsOutline )
    {
        Reference < XNamed > xNamed( xNumRules, UNO_QUERY );
        if( xNamed.is() )
        {
            bIsNamed = sal_True;
            sName = xNamed->getName();
        }

        aAny = xPropSet->getPropertyValue( sNumberingLevel );
        aAny >>= nLevel;

        bIsNumbered = sal_True;
        if( xPropSetInfo->hasPropertyByName( sNumberingIsNumber ) )
        {
            aAny = xPropSet->getPropertyValue( sNumberingIsNumber );
            OSL_ENSURE( aAny.hasValue(),
                        "numbered paragraph without number info" );
            if( !aAny.hasValue() )
                bIsNumbered = sal_False;
            else
                bIsNumbered = *(sal_Bool *)aAny.getValue();
        }

        if( bIsNumbered )
        {
            if( xPropSetInfo->hasPropertyByName( sParaIsNumberingRestart ) )
            {
                aAny = xPropSet->getPropertyValue( sParaIsNumberingRestart );
                bIsRestart = *(sal_Bool *)aAny.getValue();
            }
            if( xPropSetInfo->hasPropertyByName( sNumberingStartValue ) )
            {
                aAny = xPropSet->getPropertyValue( sNumberingStartValue );
                aAny >>= nStartValue;
            }
        }

        OSL_ENSURE( nLevel < xNumRules->getCount(), "wrong num rule level" );
        if( nLevel >= xNumRules->getCount() )
        {
            Reset();
            return;
        }

        aAny = xNumRules->getByIndex( nLevel );
        Sequence<PropertyValue> aProps;
        aAny >>= aProps;
        const PropertyValue* pPropArray = aProps.getConstArray();
        sal_Int32 nCount = aProps.getLength();
        for( sal_Int32 i=0; i<nCount; i++ )
        {
            const beans::PropertyValue& rProp = pPropArray[i];

            if( rProp.Name == sNumberingType )
            {
                sal_Int16 nType;
                rProp.Value >>= nType;
                if( NumberingType::CHAR_SPECIAL != nType &&
                    NumberingType::BITMAP != nType )
                {
                    bIsOrdered = sal_True;
                }
                break;
            }
        }
        nLevel++;
    }
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.7.202); FILE MERGED 2005/09/05 14:40:05 rt 1.7.202.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLTextNumRuleInfo.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 15:24:53 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
#include <com/sun/star/beans/PropertyValue.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXREPLACE_HPP_
#include <com/sun/star/container/XIndexReplace.hpp>
#endif
#ifndef _COM_SUN_STAR_STYLE_NUMBERINGTYPE_HPP_
#include <com/sun/star/style/NumberingType.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XNAMED_HPP_
#include <com/sun/star/container/XNamed.hpp>
#endif

#ifndef _XMLOFF_XMLTEXTNUMRULEINFO_HXX
#include "XMLTextNumRuleInfo.hxx"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::style;

XMLTextNumRuleInfo::XMLTextNumRuleInfo() :
    sNumberingRules(RTL_CONSTASCII_USTRINGPARAM("NumberingRules")),
    sNumberingLevel(RTL_CONSTASCII_USTRINGPARAM("NumberingLevel")),
    sNumberingStartValue(RTL_CONSTASCII_USTRINGPARAM("NumberingStartValue")),
    sParaIsNumberingRestart(RTL_CONSTASCII_USTRINGPARAM("ParaIsNumberingRestart")),
    sNumberingType(RTL_CONSTASCII_USTRINGPARAM("NumberingType")),
    sIsNumbering(RTL_CONSTASCII_USTRINGPARAM("IsNumbering")),
    sNumberingIsNumber(RTL_CONSTASCII_USTRINGPARAM("NumberingIsNumber")),
    sNumberingIsOutline(RTL_CONSTASCII_USTRINGPARAM("NumberingIsOutline"))
{
    Reset();
}

void XMLTextNumRuleInfo::Set(
        const ::com::sun::star::uno::Reference <
            ::com::sun::star::text::XTextContent > & xTextContent )
{
    Reset();

    Reference< XPropertySet > xPropSet( xTextContent, UNO_QUERY );
    Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();

    Any aAny;

    // check if this paragraph supports a numbering
    if( !xPropSetInfo->hasPropertyByName( sNumberingLevel ) )
        return;

    if( xPropSetInfo->hasPropertyByName( sNumberingRules ) )
    {
        aAny = xPropSet->getPropertyValue( sNumberingRules );
        aAny >>= xNumRules;
    }

    BOOL bIsOutline = FALSE;

    Reference<XPropertySet> xNumRulesProps(xNumRules, UNO_QUERY);
    if (xNumRulesProps.is() &&
        xNumRulesProps->getPropertySetInfo()->
        hasPropertyByName( sNumberingIsOutline ) )
    {
        aAny = xNumRulesProps->getPropertyValue( sNumberingIsOutline );
        bIsOutline = *(sal_Bool*)aAny.getValue();
    }

    if( xNumRules.is() && !bIsOutline )
    {
        Reference < XNamed > xNamed( xNumRules, UNO_QUERY );
        if( xNamed.is() )
        {
            bIsNamed = sal_True;
            sName = xNamed->getName();
        }

        aAny = xPropSet->getPropertyValue( sNumberingLevel );
        aAny >>= nLevel;

        bIsNumbered = sal_True;
        if( xPropSetInfo->hasPropertyByName( sNumberingIsNumber ) )
        {
            aAny = xPropSet->getPropertyValue( sNumberingIsNumber );
            OSL_ENSURE( aAny.hasValue(),
                        "numbered paragraph without number info" );
            if( !aAny.hasValue() )
                bIsNumbered = sal_False;
            else
                bIsNumbered = *(sal_Bool *)aAny.getValue();
        }

        if( bIsNumbered )
        {
            if( xPropSetInfo->hasPropertyByName( sParaIsNumberingRestart ) )
            {
                aAny = xPropSet->getPropertyValue( sParaIsNumberingRestart );
                bIsRestart = *(sal_Bool *)aAny.getValue();
            }
            if( xPropSetInfo->hasPropertyByName( sNumberingStartValue ) )
            {
                aAny = xPropSet->getPropertyValue( sNumberingStartValue );
                aAny >>= nStartValue;
            }
        }

        OSL_ENSURE( nLevel < xNumRules->getCount(), "wrong num rule level" );
        if( nLevel >= xNumRules->getCount() )
        {
            Reset();
            return;
        }

        aAny = xNumRules->getByIndex( nLevel );
        Sequence<PropertyValue> aProps;
        aAny >>= aProps;
        const PropertyValue* pPropArray = aProps.getConstArray();
        sal_Int32 nCount = aProps.getLength();
        for( sal_Int32 i=0; i<nCount; i++ )
        {
            const beans::PropertyValue& rProp = pPropArray[i];

            if( rProp.Name == sNumberingType )
            {
                sal_Int16 nType;
                rProp.Value >>= nType;
                if( NumberingType::CHAR_SPECIAL != nType &&
                    NumberingType::BITMAP != nType )
                {
                    bIsOrdered = sal_True;
                }
                break;
            }
        }
        nLevel++;
    }
}

<|endoftext|>


<commit_before>#pragma once

#include <cstddef>
#include <memory>
#include <string>
#include <vector>

#ifndef ARBITER_IS_AMALGAMATION

#include <arbiter/util/types.hpp>
#include <arbiter/util/exports.hpp>

#ifndef ARBITER_EXTERNAL_JSON
#include <arbiter/third/json/json.hpp>
#endif

#endif

#ifdef ARBITER_EXTERNAL_JSON
#include <json/json.h>
#endif

#ifdef ARBITER_CURL
#include <curl/curl.h>
#endif

#ifdef ARBITER_CUSTOM_NAMESPACE
namespace ARBITER_CUSTOM_NAMESPACE
{
#endif

namespace arbiter
{
namespace http
{

/** @cond arbiter_internal */

class Pool;

class ARBITER_DLL Curl
{
    friend class Pool;

    static constexpr std::size_t defaultHttpTimeout = 5;

public:
    ~Curl();

    http::Response get(
            std::string path,
            Headers headers,
            Query query,
            std::size_t reserve);

    http::Response head(std::string path, Headers headers, Query query);

    http::Response put(
            std::string path,
            const std::vector<char>& data,
            Headers headers,
            Query query);

    http::Response post(
            std::string path,
            const std::vector<char>& data,
            Headers headers,
            Query query);

private:
    Curl(const Json::Value& json = Json::Value());

    void init(std::string path, const Headers& headers, const Query& query);

    // Returns HTTP status code.
    int perform();

    Curl(const Curl&);
    Curl& operator=(const Curl&);

    void* m_curl = nullptr;
    curl_slist* m_headers = nullptr;

    bool m_verbose = false;
    long m_timeout = defaultHttpTimeout;
    bool m_followRedirect = true;
    bool m_verifyPeer = true;
    std::unique_ptr<std::string> m_caPath;
    std::unique_ptr<std::string> m_caInfo;

    std::vector<char> m_data;
};

/** @endcond */

} // namespace http
} // namespace arbiter

#ifdef ARBITER_CUSTOM_NAMESPACE
}
#endif

<commit_msg>Add forward declare.<commit_after>#pragma once

#include <cstddef>
#include <memory>
#include <string>
#include <vector>

#ifndef ARBITER_IS_AMALGAMATION

#include <arbiter/util/types.hpp>
#include <arbiter/util/exports.hpp>

#ifndef ARBITER_EXTERNAL_JSON
#include <arbiter/third/json/json.hpp>
#endif

#endif

#ifdef ARBITER_EXTERNAL_JSON
#include <json/json.h>
#endif

#ifdef ARBITER_CURL
#include <curl/curl.h>
#endif

struct curl_slist;

#ifdef ARBITER_CUSTOM_NAMESPACE
namespace ARBITER_CUSTOM_NAMESPACE
{
#endif

namespace arbiter
{
namespace http
{

/** @cond arbiter_internal */

class Pool;

class ARBITER_DLL Curl
{
    friend class Pool;

    static constexpr std::size_t defaultHttpTimeout = 5;

public:
    ~Curl();

    http::Response get(
            std::string path,
            Headers headers,
            Query query,
            std::size_t reserve);

    http::Response head(std::string path, Headers headers, Query query);

    http::Response put(
            std::string path,
            const std::vector<char>& data,
            Headers headers,
            Query query);

    http::Response post(
            std::string path,
            const std::vector<char>& data,
            Headers headers,
            Query query);

private:
    Curl(const Json::Value& json = Json::Value());

    void init(std::string path, const Headers& headers, const Query& query);

    // Returns HTTP status code.
    int perform();

    Curl(const Curl&);
    Curl& operator=(const Curl&);

    void* m_curl = nullptr;
    curl_slist* m_headers = nullptr;

    bool m_verbose = false;
    long m_timeout = defaultHttpTimeout;
    bool m_followRedirect = true;
    bool m_verifyPeer = true;
    std::unique_ptr<std::string> m_caPath;
    std::unique_ptr<std::string> m_caInfo;

    std::vector<char> m_data;
};

/** @endcond */

} // namespace http
} // namespace arbiter

#ifdef ARBITER_CUSTOM_NAMESPACE
}
#endif

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2010 Couchbase, Inc
 *
 *   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.
 */

#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include "libforestdb/forestdb.h"
#include "fdb_internal.h"
#include "internal_types.h"
#include "filemgr.h"
#include "common.h"
#include "list.h"
#include "wal.h"
#include "memleak.h"

LIBFDB_API
fdb_status fdb_begin_transaction(fdb_file_handle *fhandle,
                                 fdb_isolation_level_t isolation_level)
{
    fdb_kvs_handle *handle = fhandle->root;
    struct filemgr *file;

    if (handle->txn) {
        // transaction already exists
        return FDB_RESULT_TRANSACTION_FAIL;
    }
    if (handle->kvs) {
        if (handle->kvs->type == KVS_SUB) {
            // deny transaction on sub handle
            return FDB_RESULT_INVALID_HANDLE;
        }
    }

    fdb_check_file_reopen(handle, NULL);
    filemgr_mutex_lock(handle->file);
    fdb_sync_db_header(handle);
    fdb_link_new_file(handle);

    if (filemgr_is_rollback_on(handle->file)) {
        // deny beginning transaction during rollback
        filemgr_mutex_unlock(handle->file);
        return FDB_RESULT_FAIL_BY_ROLLBACK;
    }

    if (handle->new_file == NULL) {
        file = handle->file;
    } else {
        // compaction is being performed and new file exists
        // relay lock
        filemgr_mutex_lock(handle->new_file);
        filemgr_mutex_unlock(handle->file);
        file = handle->new_file;
    }

    handle->txn = (fdb_txn*)malloc(sizeof(fdb_txn));
    handle->txn->wrapper = (struct wal_txn_wrapper *)
                           malloc(sizeof(struct wal_txn_wrapper));
    handle->txn->wrapper->txn = handle->txn;
    handle->txn->handle = handle;
    if (filemgr_get_file_status(handle->file) != FILE_COMPACT_OLD) {
        // keep previous header's BID
        handle->txn->prev_hdr_bid = handle->last_hdr_bid;
    } else {
        // if file status is COMPACT_OLD,
        // then this transaction will work on new file, and
        // there is no previous header until the compaction is done.
        handle->txn->prev_hdr_bid = BLK_NOT_FOUND;
    }
    handle->txn->items = (struct list *)malloc(sizeof(struct list));
    handle->txn->isolation = isolation_level;
    list_init(handle->txn->items);
    wal_add_transaction(file, handle->txn);

    filemgr_mutex_unlock(file);

    return FDB_RESULT_SUCCESS;
}

LIBFDB_API
fdb_status fdb_abort_transaction(fdb_file_handle *fhandle)
{
    return _fdb_abort_transaction(fhandle->root);
}

fdb_status _fdb_abort_transaction(fdb_kvs_handle *handle)
{
    struct filemgr *file;

    if (handle->txn == NULL) {
        // there is no transaction started
        return FDB_RESULT_TRANSACTION_FAIL;
    }
    if (handle->kvs) {
        if (handle->kvs->type == KVS_SUB) {
            // deny transaction on sub handle
            return FDB_RESULT_INVALID_HANDLE;
        }
    }

    fdb_check_file_reopen(handle, NULL);
    if (handle->new_file == NULL) {
        file = handle->file;
        filemgr_mutex_lock(file);
        fdb_sync_db_header(handle);
        fdb_link_new_file(handle);
        if (handle->new_file) {
            // compaction is being performed and new file exists
            // relay lock
            filemgr_mutex_lock(handle->new_file);
            filemgr_mutex_unlock(handle->file);
            // reset FILE
            file = handle->new_file;
        }
    } else {
        file = handle->new_file;
        filemgr_mutex_lock(file);
        fdb_sync_db_header(handle);
    }

    wal_discard(file, handle->txn);
    wal_remove_transaction(file, handle->txn);

    free(handle->txn->items);
    free(handle->txn->wrapper);
    free(handle->txn);
    handle->txn = NULL;

    filemgr_mutex_unlock(file);

    return FDB_RESULT_SUCCESS;
}

LIBFDB_API
fdb_status fdb_end_transaction(fdb_file_handle *fhandle,
                               fdb_commit_opt_t opt)
{
    fdb_kvs_handle *handle = fhandle->root;
    struct filemgr *file;

    if (handle->txn == NULL) {
        // there is no transaction started
        return FDB_RESULT_TRANSACTION_FAIL;
    }
    if (handle->kvs) {
        if (handle->kvs->type == KVS_SUB) {
            // deny transaction on sub handle
            return FDB_RESULT_INVALID_HANDLE;
        }
    }

    fdb_status fs = FDB_RESULT_SUCCESS;
    if (list_begin(handle->txn->items)) {
        fs = _fdb_commit(handle, opt);
    }

    if (fs == FDB_RESULT_SUCCESS) {
        fdb_check_file_reopen(handle, NULL);
        if (handle->new_file == NULL) {
            file = handle->file;
            filemgr_mutex_lock(file);
            fdb_sync_db_header(handle);
            fdb_link_new_file(handle);
            if (handle->new_file) {
                // compaction is being performed and new file exists
                // relay lock
                filemgr_mutex_lock(handle->new_file);
                filemgr_mutex_unlock(handle->file);
                // reset FILE
                file = handle->new_file;
            }
        } else {
            file = handle->new_file;
            filemgr_mutex_lock(file);
            fdb_sync_db_header(handle);
        }

        wal_remove_transaction(file, handle->txn);

        free(handle->txn->items);
        free(handle->txn->wrapper);
        free(handle->txn);
        handle->txn = NULL;

        filemgr_mutex_unlock(file);
    }
    return fs;
}
<commit_msg>MB-14468 Fix potential bugs in transaction APIs<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2010 Couchbase, Inc
 *
 *   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.
 */

#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include "libforestdb/forestdb.h"
#include "fdb_internal.h"
#include "internal_types.h"
#include "filemgr.h"
#include "common.h"
#include "list.h"
#include "wal.h"
#include "memleak.h"

LIBFDB_API
fdb_status fdb_begin_transaction(fdb_file_handle *fhandle,
                                 fdb_isolation_level_t isolation_level)
{
    file_status_t fstatus;
    fdb_kvs_handle *handle = fhandle->root;
    struct filemgr *file;

    if (handle->txn) {
        // transaction already exists
        return FDB_RESULT_TRANSACTION_FAIL;
    }
    if (handle->kvs) {
        if (handle->kvs->type == KVS_SUB) {
            // deny transaction on sub handle
            return FDB_RESULT_INVALID_HANDLE;
        }
    }

    do { // repeat until file status is not REMOVED_PENDING
        fdb_check_file_reopen(handle, NULL);
        filemgr_mutex_lock(handle->file);
        fdb_sync_db_header(handle);
        fdb_link_new_file(handle);

        if (filemgr_is_rollback_on(handle->file)) {
            // deny beginning transaction during rollback
            filemgr_mutex_unlock(handle->file);
            return FDB_RESULT_FAIL_BY_ROLLBACK;
        }

        file = handle->file;
        fstatus = filemgr_get_file_status(file);
        if (fstatus == FILE_REMOVED_PENDING) {
            // we must not create transaction on this file
            // file status was changed by other thread .. start over
            filemgr_mutex_unlock(file);
        }
    } while (fstatus == FILE_REMOVED_PENDING);

    handle->txn = (fdb_txn*)malloc(sizeof(fdb_txn));
    handle->txn->wrapper = (struct wal_txn_wrapper *)
                           malloc(sizeof(struct wal_txn_wrapper));
    handle->txn->wrapper->txn = handle->txn;
    handle->txn->handle = handle;
    if (filemgr_get_file_status(handle->file) != FILE_COMPACT_OLD) {
        // keep previous header's BID
        handle->txn->prev_hdr_bid = handle->last_hdr_bid;
    } else {
        // if file status is COMPACT_OLD,
        // then this transaction will work on new file, and
        // there is no previous header until the compaction is done.
        handle->txn->prev_hdr_bid = BLK_NOT_FOUND;
    }
    handle->txn->items = (struct list *)malloc(sizeof(struct list));
    handle->txn->isolation = isolation_level;
    list_init(handle->txn->items);
    wal_add_transaction(file, handle->txn);

    filemgr_mutex_unlock(file);

    return FDB_RESULT_SUCCESS;
}

LIBFDB_API
fdb_status fdb_abort_transaction(fdb_file_handle *fhandle)
{
    return _fdb_abort_transaction(fhandle->root);
}

fdb_status _fdb_abort_transaction(fdb_kvs_handle *handle)
{
    file_status_t fstatus;
    struct filemgr *file;

    if (handle->txn == NULL) {
        // there is no transaction started
        return FDB_RESULT_TRANSACTION_FAIL;
    }
    if (handle->kvs) {
        if (handle->kvs->type == KVS_SUB) {
            // deny transaction on sub handle
            return FDB_RESULT_INVALID_HANDLE;
        }
    }

    do { // repeat until file status is not REMOVED_PENDING
        fdb_check_file_reopen(handle, NULL);

        file = handle->file;
        filemgr_mutex_lock(file);
        fdb_sync_db_header(handle);
        fdb_link_new_file(handle);

        fstatus = filemgr_get_file_status(file);
        if (fstatus == FILE_REMOVED_PENDING) {
            // we must not abort transaction on this file
            // file status was changed by other thread .. start over
            filemgr_mutex_unlock(file);
        }
    } while (fstatus == FILE_REMOVED_PENDING);

    wal_discard(file, handle->txn);
    wal_remove_transaction(file, handle->txn);

    free(handle->txn->items);
    free(handle->txn->wrapper);
    free(handle->txn);
    handle->txn = NULL;

    filemgr_mutex_unlock(file);

    return FDB_RESULT_SUCCESS;
}

LIBFDB_API
fdb_status fdb_end_transaction(fdb_file_handle *fhandle,
                               fdb_commit_opt_t opt)
{
    file_status_t fstatus;
    fdb_kvs_handle *handle = fhandle->root;
    struct filemgr *file;

    if (handle->txn == NULL) {
        // there is no transaction started
        return FDB_RESULT_TRANSACTION_FAIL;
    }
    if (handle->kvs) {
        if (handle->kvs->type == KVS_SUB) {
            // deny transaction on sub handle
            return FDB_RESULT_INVALID_HANDLE;
        }
    }

    fdb_status fs = FDB_RESULT_SUCCESS;
    if (list_begin(handle->txn->items)) {
        fs = _fdb_commit(handle, opt);
    }

    if (fs == FDB_RESULT_SUCCESS) {

        do { // repeat until file status is not REMOVED_PENDING
            fdb_check_file_reopen(handle, NULL);

            file = handle->file;
            filemgr_mutex_lock(file);
            fdb_sync_db_header(handle);
            fdb_link_new_file(handle);

            fstatus = filemgr_get_file_status(file);
            if (fstatus == FILE_REMOVED_PENDING) {
                // we must not commit transaction on this file
                // file status was changed by other thread .. start over
                filemgr_mutex_unlock(file);
            }
        } while (fstatus == FILE_REMOVED_PENDING);

        wal_remove_transaction(file, handle->txn);

        free(handle->txn->items);
        free(handle->txn->wrapper);
        free(handle->txn);
        handle->txn = NULL;

        filemgr_mutex_unlock(file);
    }
    return fs;
}
<|endoftext|>


<commit_before>// File: panorama.cc
// Date: Tue Apr 23 20:23:53 2013 +0800
// Author: Yuxin Wu <ppwwyyxxc@gmail.com>
//
#include "panorama.hh"
#include "matcher.hh"
#include "utils.hh"
#include "sift.hh"
#include "keypoint.hh"
#include "transformer.hh"
using namespace std;

imgptr Panorama::get() const {
	Matrix I(3, 3);
	I.get(0, 0) = I.get(1, 1) = I.get(2, 2) = 1;

	Coor min(0, 0), max(0, 0);
	int n = imgs.size();
	vector<Matrix> mat;
	mat.push_back(move(I));

	vector<Feature> feat1 = Panorama::get_feature(imgs[0]);
	REP(i, n - 1) {
		cout << mat[i] << endl;
		vector<Feature> feat2 = Panorama::get_feature(imgs[i + 1]);
		mat.push_back(get_transform(feat1, feat2));
		feat1 = move(feat2);
	}
	REPL(i, 2, n) mat[i] = mat[i - 1].prod(mat[i]);

	REPL(i, 0, n) {
		Vec2D corner[4] = {
			Vec2D(0, 0), Vec2D(imgs[i]->w, 0),
			Vec2D(0, imgs[i]->h), Vec2D(imgs[i]->w, imgs[i]->h)};
		for (auto &v : corner) {
			Vec2D newcorner = TransFormer::cal_project(mat[i], v);
			min.update_min(Coor(floor(newcorner.x), floor(newcorner.y)));
			max.update_max(Coor(ceil(newcorner.x), ceil(newcorner.y)));
		}
	}

	for_each(mat.begin(), mat.end(),
		[](Matrix & m) {
			Matrix inv(m.w, m.h);
			bool ok = m.inverse(inv);
			m_assert(ok);
			m = move(inv);
		});

	Coor size = max - min;
	cout << "size: " << size << endl;
	Vec2D offset(-min.x, -min.y);
	imgptr ret(new Img(size.x, size.y));
	ret->fill(Color::BLACK);

	HWTimer timer;
#pragma omp parallel for schedule(dynamic)
	REP(i, ret->h) REP(j, ret->w) {
		Vec2D final = Vec2D(j, i) - offset;
		vector<Color> blender;
		REP(k, n) {
			Vec2D old = TransFormer::cal_project(mat[k], final);
			if (between(old.x, 0, imgs[k]->w) && between(old.y, 0, imgs[k]->h))
				blender.push_back(imgs[k]->get_pixel(old.y, old.x));
		}
		if (!blender.size()) continue;
		Color finalc;
		for (auto &c : blender)
			finalc = finalc + c;
		finalc = finalc * ((real_t)1 / blender.size());
		ret->set_pixel(i, j, finalc);
	}
	print_debug("blend time: %lf secs\n", timer.get_sec());
	return ret;
}

Matrix Panorama::get_transform(const vector<Feature>& feat1, const vector<Feature>& feat2) {

	HWTimer timer;
	Matcher match(feat1, feat2);
	auto ret = match.match();
	print_debug("match time: %lf secs\n", timer.get_sec());

	TransFormer transf(ret);
	return transf.get_transform();
}

vector<Feature> Panorama::get_feature(imgptr ptr) {
	ScaleSpace ss(ptr, NUM_OCTAVE, NUM_SCALE);
	DOGSpace sp(ss);
	KeyPoint ex(sp, ss);
	ex.work();
	return move(ex.features);
}
<commit_msg>minor tweakkt<commit_after>// File: panorama.cc
// Date: Wed Apr 24 23:29:32 2013 +0800
// Author: Yuxin Wu <ppwwyyxxc@gmail.com>
//
#include "panorama.hh"
#include "matcher.hh"
#include "utils.hh"
#include "sift.hh"
#include "keypoint.hh"
#include "transformer.hh"
using namespace std;

imgptr Panorama::get() const {
	Matrix I(3, 3);
	I.get(0, 0) = I.get(1, 1) = I.get(2, 2) = 1;

	Coor min(0, 0), max(0, 0);
	int n = imgs.size();
	vector<Matrix> mat;
	mat.push_back(move(I));

	vector<Feature> feat1 = Panorama::get_feature(imgs[0]);
	REP(i, n - 1) {
		vector<Feature> feat2 = Panorama::get_feature(imgs[i + 1]);
		mat.push_back(get_transform(feat1, feat2));
		cout << mat[i + 1] << endl;
		feat1 = move(feat2);
	}
	REPL(i, 2, n) mat[i] = mat[i - 1].prod(mat[i]);

	REPL(i, 0, n) {
		Vec2D corner[4] = {
			Vec2D(0, 0), Vec2D(imgs[i]->w, 0),
			Vec2D(0, imgs[i]->h), Vec2D(imgs[i]->w, imgs[i]->h)};
		for (auto &v : corner) {
			Vec2D newcorner = TransFormer::cal_project(mat[i], v);
			min.update_min(Coor(floor(newcorner.x), floor(newcorner.y)));
			max.update_max(Coor(ceil(newcorner.x), ceil(newcorner.y)));
		}
	}

	for_each(mat.begin(), mat.end(),
		[](Matrix & m) {
			Matrix inv(m.w, m.h);
			bool ok = m.inverse(inv);
			m_assert(ok);
			m = move(inv);
		});

	Coor size = max - min;
	Vec2D offset(-min.x, -min.y);
	cout << "size: " << size << endl;
	cout << "offset" << offset << endl;;
	imgptr ret(new Img(size.x, size.y));
	ret->fill(Color::BLACK);

	HWTimer timer;
#pragma omp parallel for schedule(dynamic)
	REP(i, ret->h) REP(j, ret->w) {
		Vec2D final = Vec2D(j, i) - offset;
		vector<Color> blender;
		REP(k, n) {
			Vec2D old = TransFormer::cal_project(mat[k], final);
			if (between(old.x, 0, imgs[k]->w) && between(old.y, 0, imgs[k]->h))
				blender.push_back(imgs[k]->get_pixel(old.y, old.x));
		}
		if (!blender.size()) continue;
		Color finalc;
		for (auto &c : blender)
			finalc = finalc + c;
		finalc = finalc * ((real_t)1 / blender.size());
		ret->set_pixel(i, j, finalc);
	}
	print_debug("blend time: %lf secs\n", timer.get_sec());
	return ret;
}

Matrix Panorama::get_transform(const vector<Feature>& feat1, const vector<Feature>& feat2) {

	HWTimer timer;
	Matcher match(feat1, feat2);
	auto ret = match.match();
	print_debug("match time: %lf secs\n", timer.get_sec());

	TransFormer transf(ret);
	return transf.get_transform();
}

vector<Feature> Panorama::get_feature(imgptr ptr) {
	ScaleSpace ss(ptr, NUM_OCTAVE, NUM_SCALE);
	DOGSpace sp(ss);
	KeyPoint ex(sp, ss);
	ex.work();
	return move(ex.features);
}
<|endoftext|>


<commit_before>#include <cassert>
#include <GL/gl3w.h>
#define GLFW_INCLUDE_GL_3
#include <GLFW/glfw3.h>
#include <iostream>

bool glInit()
{
    if(gl3wInit())
    {
        return true;
    }
    return false;
}

class glframework
{
public:
    static void error_callback(int error, const char* description)
    {
        std::cerr << "[" << error << "] " << description << std::endl;
    }

    static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
    {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        {
            glfwSetWindowShouldClose(window, GL_TRUE);
        }
    }

    glframework() : window(0)
    {

    }

    ~glframework()
    {
        glfwTerminate();
    }

    bool init ()
    {
        glfwSetErrorCallback(error_callback);
        /* Initialize the library */
        if (!glfwInit())
        {
            return false;
        }

        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

        /* Create a windowed mode window and its OpenGL context */
        window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
        if (!window) {
            glfwTerminate();
            return false;
        }
        return true;
    }

    void makeCurrent()
    {
        if (window)
        {
            /* Make the window's context current */
            glfwMakeContextCurrent(window);
            glfwSetKeyCallback(window, key_callback);
        }
    }

    bool shouldContinue()
    {
        return !glfwWindowShouldClose(window);
    }

    void swapAndPollEvents()
    {
        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

private:
    GLFWwindow *window;
};

template<typename Tuto>
int tutoRunner(int argc, char **argv)
{
    glframework glfw;
    if (!glfw.init())
    {
        std::cerr<<"GLFW failed, aborting."<< std::endl;
        return -1;
    }

    glfw.makeCurrent();

    Tuto tuto;

    /* Loop until the user closes the window */
    while (glfw.shouldContinue())
    {
        tuto();
        glfw.swapAndPollEvents();
    }
    return 0;
}

class Tutorial1
{
public:
    void operator()()
    {
        static float vertices[] = {-0.5, -0.5, 0.0, 0.5, 0.5, -0.5};

        glClear(GL_COLOR_BUFFER_BIT);

        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
        glEnableVertexAttribArray(0);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        glDisableVertexAttribArray(0);

    }
};

class Tutorial2
{
public:

    Tutorial2()
    {
        GLuint VertexArrayID;
        glGenVertexArrays(1, &VertexArrayID);
        glBindVertexArray(VertexArrayID);

        // An array of 3 vectors which represents 3 vertices
        static const GLfloat g_vertex_buffer_data[] = {
           -1.0f, -1.0f, 0.0f,
           1.0f, -1.0f, 0.0f,
           0.0f,  1.0f, 0.0f,
        };

        // Generate 1 buffer, put the resulting identifier in vertexbuffer
        glGenBuffers(1, &vertexbuffer);

        // The following commands will talk about our 'vertexbuffer' buffer
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

        // Give our vertices to OpenGL.
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
    }

    void operator()()
    {
        // 1rst attribute buffer : vertices
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
           0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
           3,                  // size
           GL_FLOAT,           // type
           GL_FALSE,           // normalized?
           0,                  // stride
           (void*)0            // array buffer offset
        );

        // Draw the triangle !
        glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle

        glDisableVertexAttribArray(0);
    }

private:
    // This will identify our vertex buffer
    GLuint vertexbuffer;

};

int main(int argc, char **argv)
{
    if (!glInit())
    {
        std::cerr<<"GL init failed, aborting."<< std::endl;
        return -1;
    }

    return tutoRunner<Tutorial1>(argc, argv);
}
<commit_msg>adding support to shader in tutorial<commit_after>#include <cassert>
#include <GL/gl3w.h>
#define GLFW_INCLUDE_GL_3
#include <GLFW/glfw3.h>
#include <iostream>

bool glInit()
{
    if(gl3wInit())
    {
        return true;
    }
    return false;
}

class glframework
{
public:
    static void error_callback(int error, const char* description)
    {
        std::cerr << "[" << error << "] " << description << std::endl;
    }

    static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
    {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        {
            glfwSetWindowShouldClose(window, GL_TRUE);
        }
    }

    glframework() : window(0)
    {

    }

    ~glframework()
    {
        glfwTerminate();
    }

    bool init ()
    {
        glfwSetErrorCallback(error_callback);
        /* Initialize the library */
        if (!glfwInit())
        {
            return false;
        }

        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

        /* Create a windowed mode window and its OpenGL context */
        window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
        if (!window) {
            glfwTerminate();
            return false;
        }
        return true;
    }

    void makeCurrent()
    {
        if (window)
        {
            /* Make the window's context current */
            glfwMakeContextCurrent(window);
            glfwSetKeyCallback(window, key_callback);
        }
    }

    bool shouldContinue()
    {
        return !glfwWindowShouldClose(window);
    }

    void swapAndPollEvents()
    {
        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

private:
    GLFWwindow *window;
};

template<typename Tuto>
int tutoRunner(int argc, char **argv)
{
    glframework glfw;
    if (!glfw.init())
    {
        std::cerr<<"GLFW failed, aborting."<< std::endl;
        return -1;
    }

    glfw.makeCurrent();

    Tuto tuto;

    /* Loop until the user closes the window */
    while (glfw.shouldContinue())
    {
        tuto();
        glfw.swapAndPollEvents();
    }
    return 0;
}

class Shader
{
    friend class ShaderProgram;
public:
    explicit Shader(GLenum type) : type(type), id(0)
    {
    }

    ~Shader()
    {
        glDeleteShader(id);
    }

    bool compile(const char *source)
    {
        if (id == 0)
        {
            // Create the shaders
            id = glCreateShader(type);
            if (id == 0)
            {
                return false;
            }
        }

        glShaderSource(id, 1, &source, 0);
        glCompileShader(id);

        GLint result = GL_FALSE;

        glGetShaderiv(id, GL_COMPILE_STATUS, &result);
        if (result == GL_FALSE)
        {
            int infoLogLength = 0;
            glGetShaderiv(id, GL_INFO_LOG_LENGTH, &infoLogLength);
            char *errorMessage = new char[infoLogLength];
            glGetShaderInfoLog(id, infoLogLength, NULL, errorMessage);
            std::cerr << errorMessage << std::endl;
            delete[] errorMessage;
            return false;
        }
        return true;
    }

private:
    Shader(const Shader&);
    Shader& operator = (const Shader&);
    GLenum type;
    GLuint id;
};

class VertexShader : public Shader
{
public:
    VertexShader() : Shader(GL_FRAGMENT_SHADER)
    {
    }
};

class FragmentShader : public Shader
{
public:
    FragmentShader() : Shader(GL_VERTEX_SHADER)
    {
    }
};

class ShaderProgram
{
public:
    ShaderProgram() : id(0)
    {
    }

    ~ShaderProgram()
    {
        glDeleteProgram(id);
    }

    void add(Shader &shader)
    {
        if (shader.id)
        {
            createIfNecessary();
            glAttachShader(id, shader.id);
        }
    }

    bool link()
    {
        createIfNecessary();
        glLinkProgram(id);

        GLint result = GL_FALSE;
        // Check the program
        glGetProgramiv(id, GL_LINK_STATUS, &result);
        if (result == GL_FALSE)
        {
            int infoLogLength = 0;
            glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLogLength);
            char *errorMessage = new char[infoLogLength];
            glGetProgramInfoLog(id, infoLogLength, NULL, errorMessage);
            std::cerr << errorMessage << std::endl;
            delete[] errorMessage;
            return false;
        }
        return true;
    }

    void use()
    {
        if (id != 0)
        {
            glUseProgram(id);
        }
    }

private:
    ShaderProgram(const ShaderProgram&);
    ShaderProgram& operator = (const ShaderProgram&);

    void createIfNecessary()
    {
        if (id == 0)
        {
            id = glCreateProgram();
        }
    }

    GLuint id;
};

class Tutorial1
{
public:

    Tutorial1()
    {
        glGenVertexArrays(1, &VertexArrayID);
        glBindVertexArray(VertexArrayID);

        // An array of 3 vectors which represents 3 vertices
        static const GLfloat g_vertex_buffer_data[] = {
           -1.0f, -1.0f, 0.0f,
           1.0f, -1.0f, 0.0f,
           0.0f,  1.0f, 0.0f,
        };

        // This will identify our vertex buffer
        GLuint vertexbuffer;

        // Generate 1 buffer, put the resulting identifier in vertexbuffer
        glGenBuffers(1, &vertexbuffer);

        // The following commands will talk about our 'vertexbuffer' buffer
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

        // Give our vertices to OpenGL.
        glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

        glVertexAttribPointer(
           0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
           3,                  // size
           GL_FLOAT,           // type
           GL_FALSE,           // normalized?
           0,                  // stride
           (void*)0            // array buffer offset
        );
        glEnableVertexAttribArray(0);
        glBindVertexArray(0);
    }

    void operator()()
    {
        glBindVertexArray(VertexArrayID);

        // Draw the triangle !
        glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle

        glBindVertexArray(0);
    }

private:
    GLuint VertexArrayID;

};

class Tutorial2 : private Tutorial1
{
public:
    Tutorial2()
    {
        VertexShader vs;
        vs.compile(
                    "#version 330 core\n"
                    "in vec3 vertices;\n"
                    "void main(){\n"
                    "  gl_Position = vec4(vertices, 1);\n"
                    "}\n"
        );

        FragmentShader fs;
        vs.compile(
                    "#version 330 core\n"
                    "out vec3 color;\n"
                    "void main(){\n"
                    "  color = vec3(1, 0, 0);\n"
                    "}\n"
        );

        program.add(vs);
        program.add(fs);
        program.link();
    }

    void operator()()
    {
        program.use();
        Tutorial1::operator ()();
    }

private:
    ShaderProgram program;
};

int main(int argc, char **argv)
{
    if (!glInit())
    {
        std::cerr<<"GL init failed, aborting."<< std::endl;
        return -1;
    }

    return tutoRunner<Tutorial2>(argc, argv);
}
<|endoftext|>