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

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

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

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

=========================================================================*/
#ifndef __itkTransformFileReader_cxx
#define __itkTransformFileReader_cxx

#include "itkTransformFileReader.h"
#include "itkTransformBase.h"
#include "itkTransformFactoryBase.h"

#include <itksys/ios/sstream>

namespace itk
{

std::string trim(std::string const& source, char const* delims = " \t\r\n") {
  std::string result(source);
  std::string::size_type index = result.find_last_not_of(delims);
  if(index != std::string::npos)
    {
    result.erase(++index);
    }

  index = result.find_first_not_of(delims);
  if(index != std::string::npos)
    {
    result.erase(0, index);
    }
  else
    {
    result.erase();
    }
  return result;
}

/** Constructor */
TransformFileReader
::TransformFileReader()
{
  m_FileName = "";
  TransformFactoryBase::RegisterDefaultTransforms();
}

/** Destructor */
TransformFileReader
::~TransformFileReader()
{
}

/** Update the Reader */
void TransformFileReader
::Update()
{
  TransformPointer transform;
  std::ifstream in;
  in.open ( m_FileName.c_str(), std::ios::in | std::ios::binary );
  if( in.fail() )
    {
    in.close();
    itkExceptionMacro ( "The file could not be opened for read access "
                        << std::endl << "Filename: \"" << m_FileName << "\"" );
    }

  OStringStream InData;

  // in.get ( InData );
  std::filebuf *pbuf;
  pbuf=in.rdbuf();

  // get file size using buffer's members
  int size=pbuf->pubseekoff (0,std::ios::end,std::ios::in);
  pbuf->pubseekpos (0,std::ios::in);

  // allocate memory to contain file data
  char* buffer=new char[size+1];

  // get file data
  pbuf->sgetn (buffer,size);
  buffer[size]='\0';
  itkDebugMacro ( "Read file transform Data" );
  InData << buffer;

  delete[] buffer;
  std::string data = InData.str();
  in.close();

  // Read line by line
  vnl_vector<double> VectorBuffer;
  std::string::size_type position = 0;

  Array<double> TmpParameterArray;
  Array<double> TmpFixedParameterArray;
  TmpParameterArray.clear();
  TmpFixedParameterArray.clear();
  bool haveFixedParameters = false;
  bool haveParameters = false;

  while ( position < data.size() )
    {
    // Find the next string
    std::string::size_type end = data.find ( "\n", position );
    std::string line = trim ( data.substr ( position, end - position ) );
    position = end+1;
    itkDebugMacro ("Found line: \"" << line << "\"" );

    if ( line.length() == 0 )
      {
      continue;
      }
    if ( line[0] == '#' || std::string::npos == line.find_first_not_of ( " \t" ) )
      {
      // Skip lines beginning with #, or blank lines
      continue;
      }

    // Get the name
    end = line.find ( ":" );
    if ( end == std::string::npos )
      {
      // Throw an error
      itkExceptionMacro ( "Tags must be delimited by :" );
      }
    std::string Name = trim ( line.substr ( 0, end ) );
    std::string Value = trim ( line.substr ( end + 1, line.length() ) );
    // Push back
    itkDebugMacro ( "Name: \"" << Name << "\"" );
    itkDebugMacro ( "Value: \"" << Value << "\"" );
    itksys_ios::istringstream parse ( Value );
    VectorBuffer.clear();
    if ( Name == "Transform" )
      {
      // Instantiate the transform
      itkDebugMacro ( "About to call ObjectFactory" );
      LightObject::Pointer i;
      i = ObjectFactoryBase::CreateInstance ( Value.c_str() );
      itkDebugMacro ( "After call ObjectFactory");
      TransformType* ptr = dynamic_cast<TransformBase*> ( i.GetPointer() );
      if ( ptr == NULL )
        {
        // itkExceptionMacro ( "Failed to create instance of" << Value );
        OStringStream msg;
        msg << "Could not create an instance of " << Value << std::endl
            << "The usual cause of this error is not registering the "
            << "transform with TransformFactory" << std::endl;
        msg << "Currently registered Transforms: " << std::endl;
        itkExceptionMacro ( << msg.str() );
        std::list<std::string> names = TransformFactoryBase::GetFactory()->GetClassOverrideWithNames();
        std::list<std::string>::iterator it;
        for ( it = names.begin(); it != names.end(); it++ )
          {
          msg << "\t\"" << *it << "\"" << std::endl;
          }
        itkExceptionMacro ( << msg.str() );
        return;
        }
      transform = ptr;
      m_TransformList.push_back ( transform );
      }
    else if ( Name == "Parameters" || Name == "FixedParameters" )
      {
      VectorBuffer.clear();

      // Read them
      parse >> VectorBuffer;
      itkDebugMacro ( "Parsed: " << VectorBuffer );
      if ( Name == "Parameters" )
        {
        TmpParameterArray = VectorBuffer;
        itkDebugMacro ( "Setting Parameters: " << TmpParameterArray );
        if ( haveFixedParameters )
          {
          transform->SetFixedParameters ( TmpFixedParameterArray );
          itkDebugMacro ( "Set Transform Fixed Parameters" );
          transform->SetParametersByValue ( TmpParameterArray );
          itkDebugMacro ( "Set Transform Parameters" );
          TmpParameterArray.clear();
          TmpFixedParameterArray.clear();
          haveFixedParameters = false;
          haveParameters = false;
          }
        else
          {
          haveParameters = true;
          }
        }
      else if ( Name == "FixedParameters" )
        {
        TmpFixedParameterArray = VectorBuffer;
        itkDebugMacro ( "Setting Fixed Parameters: " << TmpFixedParameterArray );
        if ( !transform )
          {
          itkExceptionMacro ( "Please set the transform before parameters or fixed parameters" );
          }
        if ( haveParameters )
          {
          transform->SetFixedParameters ( TmpFixedParameterArray );
          itkDebugMacro ( "Set Transform Fixed Parameters" );
          transform->SetParametersByValue ( TmpParameterArray );
          itkDebugMacro ( "Set Transform Parameters" );
          TmpParameterArray.clear();
          TmpFixedParameterArray.clear();
          haveFixedParameters = false;
          haveParameters = false;
          }
        else
          {
          haveFixedParameters = true;
          }
        }
      }
    }
}

} // namespace itk

#endif
<commit_msg>BUG: 5293. The redunant and premature call to the itkExceptionMacro() has been removed.<commit_after>/*=========================================================================

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

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

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

=========================================================================*/
#ifndef __itkTransformFileReader_cxx
#define __itkTransformFileReader_cxx

#include "itkTransformFileReader.h"
#include "itkTransformBase.h"
#include "itkTransformFactoryBase.h"

#include <itksys/ios/sstream>

namespace itk
{

std::string trim(std::string const& source, char const* delims = " \t\r\n") {
  std::string result(source);
  std::string::size_type index = result.find_last_not_of(delims);
  if(index != std::string::npos)
    {
    result.erase(++index);
    }

  index = result.find_first_not_of(delims);
  if(index != std::string::npos)
    {
    result.erase(0, index);
    }
  else
    {
    result.erase();
    }
  return result;
}

/** Constructor */
TransformFileReader
::TransformFileReader()
{
  m_FileName = "";
  TransformFactoryBase::RegisterDefaultTransforms();
}

/** Destructor */
TransformFileReader
::~TransformFileReader()
{
}

/** Update the Reader */
void TransformFileReader
::Update()
{
  TransformPointer transform;
  std::ifstream in;
  in.open ( m_FileName.c_str(), std::ios::in | std::ios::binary );
  if( in.fail() )
    {
    in.close();
    itkExceptionMacro ( "The file could not be opened for read access "
                        << std::endl << "Filename: \"" << m_FileName << "\"" );
    }

  OStringStream InData;

  // in.get ( InData );
  std::filebuf *pbuf;
  pbuf=in.rdbuf();

  // get file size using buffer's members
  int size=pbuf->pubseekoff (0,std::ios::end,std::ios::in);
  pbuf->pubseekpos (0,std::ios::in);

  // allocate memory to contain file data
  char* buffer=new char[size+1];

  // get file data
  pbuf->sgetn (buffer,size);
  buffer[size]='\0';
  itkDebugMacro ( "Read file transform Data" );
  InData << buffer;

  delete[] buffer;
  std::string data = InData.str();
  in.close();

  // Read line by line
  vnl_vector<double> VectorBuffer;
  std::string::size_type position = 0;

  Array<double> TmpParameterArray;
  Array<double> TmpFixedParameterArray;
  TmpParameterArray.clear();
  TmpFixedParameterArray.clear();
  bool haveFixedParameters = false;
  bool haveParameters = false;

  while ( position < data.size() )
    {
    // Find the next string
    std::string::size_type end = data.find ( "\n", position );
    std::string line = trim ( data.substr ( position, end - position ) );
    position = end+1;
    itkDebugMacro ("Found line: \"" << line << "\"" );

    if ( line.length() == 0 )
      {
      continue;
      }
    if ( line[0] == '#' || std::string::npos == line.find_first_not_of ( " \t" ) )
      {
      // Skip lines beginning with #, or blank lines
      continue;
      }

    // Get the name
    end = line.find ( ":" );
    if ( end == std::string::npos )
      {
      // Throw an error
      itkExceptionMacro ( "Tags must be delimited by :" );
      }
    std::string Name = trim ( line.substr ( 0, end ) );
    std::string Value = trim ( line.substr ( end + 1, line.length() ) );
    // Push back
    itkDebugMacro ( "Name: \"" << Name << "\"" );
    itkDebugMacro ( "Value: \"" << Value << "\"" );
    itksys_ios::istringstream parse ( Value );
    VectorBuffer.clear();
    if ( Name == "Transform" )
      {
      // Instantiate the transform
      itkDebugMacro ( "About to call ObjectFactory" );
      LightObject::Pointer i;
      i = ObjectFactoryBase::CreateInstance ( Value.c_str() );
      itkDebugMacro ( "After call ObjectFactory");
      TransformType* ptr = dynamic_cast<TransformBase*> ( i.GetPointer() );
      if ( ptr == NULL )
        {
        OStringStream msg;
        msg << "Could not create an instance of " << Value << std::endl
            << "The usual cause of this error is not registering the "
            << "transform with TransformFactory" << std::endl;
        msg << "Currently registered Transforms: " << std::endl;
        std::list<std::string> names = TransformFactoryBase::GetFactory()->GetClassOverrideWithNames();
        std::list<std::string>::iterator it;
        for ( it = names.begin(); it != names.end(); it++ )
          {
          msg << "\t\"" << *it << "\"" << std::endl;
          }
        itkExceptionMacro ( << msg.str() );
        return;
        }
      transform = ptr;
      m_TransformList.push_back ( transform );
      }
    else if ( Name == "Parameters" || Name == "FixedParameters" )
      {
      VectorBuffer.clear();

      // Read them
      parse >> VectorBuffer;
      itkDebugMacro ( "Parsed: " << VectorBuffer );
      if ( Name == "Parameters" )
        {
        TmpParameterArray = VectorBuffer;
        itkDebugMacro ( "Setting Parameters: " << TmpParameterArray );
        if ( haveFixedParameters )
          {
          transform->SetFixedParameters ( TmpFixedParameterArray );
          itkDebugMacro ( "Set Transform Fixed Parameters" );
          transform->SetParametersByValue ( TmpParameterArray );
          itkDebugMacro ( "Set Transform Parameters" );
          TmpParameterArray.clear();
          TmpFixedParameterArray.clear();
          haveFixedParameters = false;
          haveParameters = false;
          }
        else
          {
          haveParameters = true;
          }
        }
      else if ( Name == "FixedParameters" )
        {
        TmpFixedParameterArray = VectorBuffer;
        itkDebugMacro ( "Setting Fixed Parameters: " << TmpFixedParameterArray );
        if ( !transform )
          {
          itkExceptionMacro ( "Please set the transform before parameters or fixed parameters" );
          }
        if ( haveParameters )
          {
          transform->SetFixedParameters ( TmpFixedParameterArray );
          itkDebugMacro ( "Set Transform Fixed Parameters" );
          transform->SetParametersByValue ( TmpParameterArray );
          itkDebugMacro ( "Set Transform Parameters" );
          TmpParameterArray.clear();
          TmpFixedParameterArray.clear();
          haveFixedParameters = false;
          haveParameters = false;
          }
        else
          {
          haveFixedParameters = true;
          }
        }
      }
    }
}

} // namespace itk

#endif
<|endoftext|>


<commit_before>#include "nbodysimulation.h"

typedef NBodySimulation::Record Record;

NBodySimulation::NBodySimulation(unsigned int boundary)
  : index_(1), boundary_(boundary), time_(0)
{}

//appends the internal list of spheres with the given attributes of a sphere
void NBodySimulation::addBody(Color color, const Vector3& center,
  int radius, const Vector3& velocity)
{
  // initializes with acceleration of 0 and mass equal to radius
  SimulatedBody body =
    SimulatedBody(center, radius, velocity, Vector3(0,0,0), radius);

  ManagedBody indexed_body = { index_, body, color };

  if(color == Color::kBlack)
    massless_bodies_.push_back(indexed_body);
  else
     bodies_.push_back(indexed_body);

  index_++;
}

//assigns the properties to the black hole and adds it to the list of black holes
void NBodySimulation::addBlackHole(const Vector3& center, int mass)
{
  SimulatedBody black_hole;
  black_hole.setCenter(center);
  black_hole.setMass(mass);
  black_holes_.push_back(black_hole);
}

//Returns a vector of records detailing how and when the bodies collided
std::vector<NBodySimulation::Record> NBodySimulation::getSimulationResults()
{
  return records_;
}

//*TODO* add check for stable orbits
// run until all spheres have collided
void NBodySimulation::runSimulation()
{
  while(! bodies_.empty() || ! massless_bodies_.empty()) {
    findAllOverlaps();
    updateAllForces();
    advance(TIMEINTERVAL);
  }
}

void NBodySimulation::updateAllForces()
{
  resetForces(); //start from 0
  calculateForcesFromBodies();
  calculateForcesFromMasslessBodies();
  calculateForcesFromBlackHoles();
}

// calculates the forces for the current frame and advances the spheres by the
// given time interval
void NBodySimulation::advance(double time) {
  for(ManagedBodyIterator i = bodies_.begin(); i != bodies_.end(); ++i) {
    i->body.advance(time);
  }
  for(ManagedBodyIterator i = massless_bodies_.begin(); i != massless_bodies_.end(); ++i) {
    i->body.advance(time);
  }

  time_ += time;
}

//set the forces of each body to 0
void NBodySimulation::resetForces()
{
  typedef std::list<NBodySimulation::ManagedBody>::iterator ManagedBodyIterator;
  for(ManagedBodyIterator i = bodies_.begin(); i != bodies_.end(); ++i)
    i->body.setForce(Vector3(0,0,0));
}

void NBodySimulation::calculateForcesFromMasslessBodies()
{
  for(ManagedBodyIterator i = bodies_.begin(); i != bodies_.end(); ++i) {
    for(ManagedBodyIterator j = massless_bodies_.begin(); j != massless_bodies_.end(); ++j) {
      updateForce(i->body, j->body);
      j->body.setForce(Vector3(0,0,0)); //massless bodies not affected by mass
    }
  }
}

//n^2 iteration calculating and applying the forc
void NBodySimulation::calculateForcesFromBodies()
{
  ManagedBodyIterator i = bodies_.begin();
  while(i != bodies_.end()) {
    ManagedBodyIterator j = i; //not necessary to start at beginning

    //bodies do apply a force on themselves
    for(j++; j != bodies_.end(); ++j) {
      updateForce(i->body, j->body);
    }
    i++;
  };
}

void NBodySimulation::calculateForcesFromBlackHoles()
{
  for(ManagedBodyIterator i = bodies_.begin(); i != bodies_.end(); ++i) {
    for(SimulatedBodyIterator j = black_holes_.begin(); j != black_holes_.end(); ++j)
      updateForce(i->body, *j);
  }
}

void NBodySimulation::updateForce(SimulatedBody &b1, SimulatedBody &b2)
{
  Gravity::PointMass m1 = { b1.getMass(), b1.getCenter() };
  Gravity::PointMass m2 = { b2.getMass(), b2.getCenter() };

  Vector3 force = Gravity::force(m1, m2, GRAVITY);
  b1.setForce(b1.getForce() + force);
  b2.setForce(b2.getForce() + force * -1);
}

//*TODO* refactor this huge, monolithic function
//n^2 traversal creating complete list of all possible collisions
void NBodySimulation::findAllOverlaps()
{
  if(bodies_.size() <= 0 && massless_bodies_.size() <= 0) //no spheres to check collisions with
    return;

  std::list<Collision> collisions;

  //check overlap of bodies with black holes
  ManagedBodyIterator i = bodies_.begin();
  while(i != bodies_.end()) {
    for(SimulatedBodyIterator j = black_holes_.begin(); j != black_holes_.end(); ++j) {
      if(COLLISION::isOverlapping(i->body, j->getCenter())) {
        recordEvent(*i, time_, CollisionType::kBlackHole);
        i = bodies_.erase(i); //erase body from existence
      } else {
        ++i;
      }
    }
  };

  i = bodies_.begin();

  //check overlap between bodies with other bodies
  while(i != bodies_.end()) {
    ManagedBodyIterator j = i; //not necessary to start at beginning
    ++j; //bodies do not collide with themselves

    bool eraseI = false;
    while(j != bodies_.end()) {
      if(COLLISION::isOverlapping(i->body, j->body)) { //overlap found
        if(i->body.getRadius() > j->body.getRadius()) { // j is smaller
          recordEvent(*j, time_, CollisionType::kCollision);
          j = bodies_.erase(j);
        } else {
          recordEvent(*i, time_, CollisionType::kCollision);
          i = bodies_.erase(i);
          eraseI = true;
          break; // do not compare i with rest of values
        }
      }
      else
        ++j;
    };

    if(!eraseI) { //check against massless bodies
      for(ManagedBodyIterator k = massless_bodies_.begin(); k != massless_bodies_.end(); ++k) {
        if(COLLISION::isOverlapping(i->body, k->body)) {
          recordEvent(*i, time_, CollisionType::kCollision);
          i = bodies_.erase(i);
          eraseI = true;
          break; // do not compare i with rest of the massless bodies
        }
      }
    }

    if(!eraseI) // do not double increment
      i++;
  };

  // check collision with boundary
  i = bodies_.begin();
  while(i != bodies_.end()) {
    if(isOverlappingBoundary(i->body)) {
      recordEvent(*i, time_, CollisionType::kBoundary);
      isOverlappingBoundary(i->body);
      i = bodies_.erase(i);
    } else
      ++i;
  };

  i = massless_bodies_.begin();
  while(i != massless_bodies_.end()) {
    if(isOverlappingBoundary(i->body)) {
      recordEvent(*i, time_, CollisionType::kBoundary);
      i = massless_bodies_.erase(i);
    } else
      ++i;
  };
}

bool NBodySimulation::isOverlappingBoundary(const Sphere &sphere)
{
  Vector3 center = sphere.getCenter();
  int radius = sphere.getRadius();

  for(int i = 0; i < 3; ++i) {
    if(center[i] + radius > boundary_ || center[i] - radius < 0)
      return true;
  }
  return false;
}

void NBodySimulation::recordEvent(
  const ManagedBody &body, double time, NBodySimulation::CollisionType type)
{
  Record record = { body.index, body.color, time, type };
  records_.push_back(record);
}<commit_msg>Changed massless_bodies to freemoving_bodies<commit_after>#include "nbodysimulation.h"

typedef NBodySimulation::Record Record;

NBodySimulation::NBodySimulation(unsigned int boundary)
  : index_(1), boundary_(boundary), time_(0)
{}

//appends the internal list of spheres with the given attributes of a sphere
void NBodySimulation::addBody(Color color, const Vector3& center,
  int radius, const Vector3& velocity)
{
  // initializes with acceleration of 0 and mass equal to radius
  SimulatedBody body =
    SimulatedBody(center, radius, velocity, Vector3(0,0,0), radius);

  ManagedBody indexed_body = { index_, body, color };

  if(color == Color::kBlack)
    freemoving_bodies_.push_back(indexed_body);
  else
     bodies_.push_back(indexed_body);

  index_++;
}

//assigns the properties to the black hole and adds it to the list of black holes
void NBodySimulation::addBlackHole(const Vector3& center, int mass)
{
  SimulatedBody black_hole;
  black_hole.setCenter(center);
  black_hole.setMass(mass);
  black_holes_.push_back(black_hole);
}

//Returns a vector of records detailing how and when the bodies collided
std::vector<NBodySimulation::Record> NBodySimulation::getSimulationResults()
{
  return records_;
}

//*TODO* add check for stable orbits
// run until all spheres have collided
void NBodySimulation::runSimulation()
{
  while(! bodies_.empty() || ! freemoving_bodies_.empty()) {
    findAllOverlaps();
    updateAllForces();
    advance(TIMEINTERVAL);
  }
}

// calculates
void NBodySimulation::updateAllForces()
{
  resetForces(); //start from 0
  calculateForcesFromBodies();
  calculateForcesFromFreeMovingBodies();
  calculateForcesFromBlackHoles();
}

// calculates the forces for the current frame and advances the spheres by the
// given time interval
void NBodySimulation::advance(double time) {
  for(ManagedBodyIterator i = bodies_.begin(); i != bodies_.end(); ++i) {
    i->body.advance(time);
  }
  for(ManagedBodyIterator i = freemoving_bodies_.begin(); i != freemoving_bodies_.end(); ++i) {
    i->body.advance(time);
  }

  time_ += time;
}

//set the forces of each body to 0
void NBodySimulation::resetForces()
{
  typedef std::list<NBodySimulation::ManagedBody>::iterator ManagedBodyIterator;
  for(ManagedBodyIterator i = bodies_.begin(); i != bodies_.end(); ++i)
    i->body.setForce(Vector3(0,0,0));
}

void NBodySimulation::calculateForcesFromFreeMovingBodies()
{
  for(ManagedBodyIterator i = bodies_.begin(); i != bodies_.end(); ++i) {
    for(ManagedBodyIterator j = freemoving_bodies_.begin(); j != freemoving_bodies_.end(); ++j) {
      updateForce(i->body, j->body);
      j->body.setForce(Vector3(0,0,0)); //massless bodies not affected by mass
    }
  }
}

//n^2 iteration calculating and applying the forc
void NBodySimulation::calculateForcesFromBodies()
{
  ManagedBodyIterator i = bodies_.begin();
  while(i != bodies_.end()) {
    ManagedBodyIterator j = i; //not necessary to start at beginning

    //bodies do apply a force on themselves
    for(j++; j != bodies_.end(); ++j) {
      updateForce(i->body, j->body);
    }
    i++;
  };
}

void NBodySimulation::calculateForcesFromBlackHoles()
{
  for(ManagedBodyIterator i = bodies_.begin(); i != bodies_.end(); ++i) {
    for(SimulatedBodyIterator j = black_holes_.begin(); j != black_holes_.end(); ++j)
      updateForce(i->body, *j);
  }
}

void NBodySimulation::updateForce(SimulatedBody &b1, SimulatedBody &b2)
{
  Gravity::PointMass m1 = { b1.getMass(), b1.getCenter() };
  Gravity::PointMass m2 = { b2.getMass(), b2.getCenter() };

  Vector3 force = Gravity::force(m1, m2, GRAVITY);
  b1.setForce(b1.getForce() + force);
  b2.setForce(b2.getForce() + force * -1);
}

//*TODO* refactor this huge, monolithic function
//n^2 traversal creating complete list of all possible collisions
void NBodySimulation::findAllOverlaps()
{
  if(bodies_.size() <= 0 && freemoving_bodies_.size() <= 0) //no spheres to check collisions with
    return;

  //check overlap of bodies with black holes
  ManagedBodyIterator i = bodies_.begin();
  while(i != bodies_.end()) {
    for(SimulatedBodyIterator j = black_holes_.begin(); j != black_holes_.end(); ++j) {
      if(COLLISION::isOverlapping(i->body, j->getCenter())) {
        recordEvent(*i, time_, CollisionType::kBlackHole);
        i = bodies_.erase(i); //erase body from existence
      } else {
        ++i;
      }
    }
  };

  i = bodies_.begin();

  //check overlap between bodies with other bodies
  while(i != bodies_.end()) {
    ManagedBodyIterator j = i; //not necessary to start at beginning
    ++j; //bodies do not collide with themselves

    bool eraseI = false;
    while(j != bodies_.end()) {
      if(COLLISION::isOverlapping(i->body, j->body)) { //overlap found
        if(i->body.getRadius() > j->body.getRadius()) { // j is smaller
          recordEvent(*j, time_, CollisionType::kCollision);
          j = bodies_.erase(j);
        } else {
          recordEvent(*i, time_, CollisionType::kCollision);
          i = bodies_.erase(i);
          eraseI = true;
          break; // do not compare i with rest of values
        }
      }
      else
        ++j;
    };

    if(!eraseI) { //check against massless bodies
      for(ManagedBodyIterator k = freemoving_bodies_.begin(); k != freemoving_bodies_.end(); ++k) {
        if(COLLISION::isOverlapping(i->body, k->body)) {
          recordEvent(*i, time_, CollisionType::kCollision);
          i = bodies_.erase(i);
          eraseI = true;
          break; // do not compare i with rest of the massless bodies
        }
      }
    }

    if(!eraseI) // do not double increment
      i++;
  };

  // check collision with boundary
  i = bodies_.begin();
  while(i != bodies_.end()) {
    if(isOverlappingBoundary(i->body)) {
      recordEvent(*i, time_, CollisionType::kBoundary);
      isOverlappingBoundary(i->body);
      i = bodies_.erase(i);
    } else
      ++i;
  };

  i = freemoving_bodies_.begin();
  while(i != freemoving_bodies_.end()) {
    if(isOverlappingBoundary(i->body)) {
      recordEvent(*i, time_, CollisionType::kBoundary);
      i = freemoving_bodies_.erase(i);
    } else
      ++i;
  };
}

bool NBodySimulation::isOverlappingBoundary(const Sphere &sphere)
{
  Vector3 center = sphere.getCenter();
  int radius = sphere.getRadius();

  for(int i = 0; i < 3; ++i) {
    if(center[i] + radius > boundary_ || center[i] - radius < 0)
      return true;
  }
  return false;
}

void NBodySimulation::recordEvent(
  const ManagedBody &body, double time, NBodySimulation::CollisionType type)
{
  Record record = { body.index, body.color, time, type };
  records_.push_back(record);
}<|endoftext|>


<commit_before>// Copyright (c) 2018 The Gulden developers
// Authored by: Willem de Jonge (willem@isnapp.nl)
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <string>
#include "../unity_impl.h"
#include "gulden_unified_frontend.hpp"

void OpenDebugLog()
{
}

int LogPrintStr(const std::string &str)
{
    if (signalHandler)
    {
        signalHandler->logPrint(str);
    }
    return str.size();
}
<commit_msg>SPV: Log to file foe electron builds<commit_after>// Copyright (c) 2018 The Gulden developers
// Authored by: Willem de Jonge (willem@isnapp.nl)
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "util.h"
#include "fs.h"
#include <boost/thread.hpp>
#include "../unity_impl.h"
#include "gulden_unified_frontend.hpp"

static boost::once_flag debugPrintInitFlag = BOOST_ONCE_INIT;

/**
 * We use boost::call_once() to make sure mutexDebugLog and
 * vMsgsBeforeOpenLog are initialized in a thread-safe manner.
 *
 * NOTE: fileout, mutexDebugLog and sometimes vMsgsBeforeOpenLog
 * are leaked on exit. This is ugly, but will be cleaned up by
 * the OS/libc. When the shutdown sequence is fully audited and
 * tested, explicit destruction of these objects can be implemented.
 */
static FILE* fileout = NULL;
static boost::mutex* mutexDebugLog = NULL;
static std::list<std::string>* vMsgsBeforeOpenLog;

static int FileWriteStr(const std::string &str, FILE *fp)
{
    return fwrite(str.data(), 1, str.size(), fp);
}

static void DebugPrintInit()
{
    assert(mutexDebugLog == NULL);
    mutexDebugLog = new boost::mutex();
    vMsgsBeforeOpenLog = new std::list<std::string>;
}

void OpenDebugLog()
{
    boost::call_once(&DebugPrintInit, debugPrintInitFlag);
    boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);

    assert(fileout == NULL);
    assert(vMsgsBeforeOpenLog);
    fs::path pathDebug = GetDataDir() / "debug.log";
    fileout = fsbridge::fopen(pathDebug, "a");
    if (fileout) {
        setbuf(fileout, NULL); // unbuffered
        // dump buffered messages from before we opened the log
        while (!vMsgsBeforeOpenLog->empty()) {
            FileWriteStr(vMsgsBeforeOpenLog->front(), fileout);
            vMsgsBeforeOpenLog->pop_front();
        }
    }

    delete vMsgsBeforeOpenLog;
    vMsgsBeforeOpenLog = NULL;
}

/**
 * fStartedNewLine is a state variable held by the calling context that will
 * suppress printing of the timestamp when multiple calls are made that don't
 * end in a newline. Initialize it to true, and hold it, in the calling context.
 */
static std::string LogTimestampStr(const std::string &str, std::atomic_bool *fStartedNewLine)
{
    std::string strStamped;

    if (!fLogTimestamps)
        return str;

    if (*fStartedNewLine) {
        int64_t nTimeMicros = GetTimeMicros();
        strStamped = DateTimeStrFormat("%Y-%m-%d %H:%M:%S", nTimeMicros/1000000);
        if (fLogTimeMicros)
            strStamped += strprintf(".%06d", nTimeMicros%1000000);
        int64_t mocktime = GetMockTime();
        if (mocktime) {
            strStamped += " (mocktime: " + DateTimeStrFormat("%Y-%m-%d %H:%M:%S", mocktime) + ")";
        }
        strStamped += ' ' + str;
    } else
        strStamped = str;

    if (!str.empty() && str[str.size()-1] == '\n')
        *fStartedNewLine = true;
    else
        *fStartedNewLine = false;

    return strStamped;
}

int LogPrintStr(const std::string &str)
{
    int ret = 0; // Returns total number of characters written
    static std::atomic_bool fStartedNewLine(true);

    if (signalHandler)
    {
        signalHandler->logPrint(str);
    }

    std::string strTimestamped = LogTimestampStr(str, &fStartedNewLine);

    boost::call_once(&DebugPrintInit, debugPrintInitFlag);
    boost::mutex::scoped_lock scoped_lock(*mutexDebugLog);

    // buffer if we haven't opened the log yet
    if (fileout == NULL) {
        assert(vMsgsBeforeOpenLog);
        ret = strTimestamped.length();
        vMsgsBeforeOpenLog->push_back(strTimestamped);
    }
    else
    {
        // reopen the log file, if requested
        if (fReopenDebugLog) {
            fReopenDebugLog = false;
            fs::path pathDebug = GetDataDir() / "debug.log";
            if (fsbridge::freopen(pathDebug,"a",fileout) != NULL)
                setbuf(fileout, NULL); // unbuffered
        }

        ret = FileWriteStr(strTimestamped, fileout);
    }
    return ret;
}

<|endoftext|>


<commit_before>// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.

#ifndef UTF8_VALIDATOR_HPP
#define UTF8_VALIDATOR_HPP

#include <stdint.h>

namespace utf8_validator {

static const int UTF8_ACCEPT = 0;
static const int UTF8_REJECT = 1;

static const uint8_t utf8d[] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
  8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
  0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
  0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
  0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
  1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
  1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
  1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
};

uint32_t inline
decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
  uint32_t type = utf8d[byte];

  *codep = (*state != UTF8_ACCEPT) ?
    (byte & 0x3fu) | (*codep << 6) :
    (0xff >> type) & (byte);

  *state = utf8d[256 + *state*16 + type];
  return *state;
}

class validator {
public:
	validator() : m_state(UTF8_ACCEPT),m_codepoint(0) {}

	bool consume (uint32_t byte) {
		if (utf8_validator::decode(&m_state,&m_codepoint,byte) == UTF8_REJECT) {
			return false;
		}
		return true;
	}

	template <typename iterator_type>
	bool decode (iterator_type b, iterator_type e) {
		for (iterator_type i = b; i != e; i++) {
			if (utf8_validator::decode(&m_state,&m_codepoint,*i) == UTF8_REJECT) {
				return false;
			}
		}
		return true;
	}

	bool complete() {
		return m_state == UTF8_ACCEPT;
	}

	void reset() {
		m_state = UTF8_ACCEPT;
		m_codepoint = 0;
	}
private:
	uint32_t	m_state;
	uint32_t	m_codepoint;
};

// convenience function that creates a validator, validates a complete string
// and returns the result.
// TODO: should this be inline?
inline bool validate(const std::string& s) {
	validator v;
	if (!v.decode(s.begin(),s.end())) {
		return false;
	}
	return v.complete();
}

} // namespace utf8_validator

#endif // UTF8_VALIDATOR_HPP<commit_msg>fixes formatting<commit_after>// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.

#ifndef UTF8_VALIDATOR_HPP
#define UTF8_VALIDATOR_HPP

#include <stdint.h>

namespace utf8_validator {

static const int UTF8_ACCEPT = 0;
static const int UTF8_REJECT = 1;

static const uint8_t utf8d[] = {
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
  8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
  0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
  0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
  0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
  1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
  1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
  1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
};

uint32_t inline
decode(uint32_t* state, uint32_t* codep, uint32_t byte) {
  uint32_t type = utf8d[byte];

  *codep = (*state != UTF8_ACCEPT) ?
    (byte & 0x3fu) | (*codep << 6) :
    (0xff >> type) & (byte);

  *state = utf8d[256 + *state*16 + type];
  return *state;
}

class validator {
public:
	validator() : m_state(UTF8_ACCEPT),m_codepoint(0) {}

	bool consume (uint32_t byte) {
		if (utf8_validator::decode(&m_state,&m_codepoint,byte) == UTF8_REJECT) {
			return false;
		}
		return true;
	}

	template <typename iterator_type>
	bool decode (iterator_type b, iterator_type e) {
		for (iterator_type i = b; i != e; i++) {
			if (utf8_validator::decode(&m_state,&m_codepoint,*i) == UTF8_REJECT) {
				return false;
			}
		}
		return true;
	}

	bool complete() {
		return m_state == UTF8_ACCEPT;
	}

	void reset() {
		m_state = UTF8_ACCEPT;
		m_codepoint = 0;
	}
private:
	uint32_t	m_state;
	uint32_t	m_codepoint;
};

// convenience function that creates a validator, validates a complete string
// and returns the result.
// TODO: should this be inline?
inline bool validate(const std::string& s) {
	validator v;
	if (!v.decode(s.begin(),s.end())) {
		return false;
	}
	return v.complete();
}

} // namespace utf8_validator

#endif // UTF8_VALIDATOR_HPP<|endoftext|>


<commit_before>#include "main_window.hpp"
#include "key_event.hpp"
#include "open_dialog.hpp"
#include "save_dialog.hpp"
#include "text_file.hpp"
#include "dialog.hpp"
#include "application.hpp"
#include <algorithm>
#include <cassert>

MainWindow::MainWindow(Widget *parent):
    Widget(parent),
    activeScreen_(nullptr),
    layout_(Layout::Vertical),
    tabs_(this),
    statusBar_(this),
    screenLayout_(Layout::Vertical)
{
    activeScreen_ = new Screen(this);
    connect(SIGNAL(&tabs_, setTextBuffer), SLOT(this, setTextBuffer));
    connect(SIGNAL(&tabs_, deleteTextBuffer), SLOT(this, deleteTextBuffer));
    activeScreen_->setStatusBar(&statusBar_);
    setLayout(&layout_);
    layout_.addLayoutable(&tabs_);
    screenLayout_.addLayoutable(activeScreen_);
    layout_.addLayoutable(&screenLayout_);
    layout_.addLayoutable(&statusBar_);
    activeScreen_->setFocus();
}

bool MainWindow::keyPressEvent(KeyEvent &e)
{
    bool result1 = true;
    switch (e.modifiers())
    {
    case KeyEvent::MLCtrl:
    case KeyEvent::MRCtrl:
        switch (e.key())
        {
        case KeyEvent::K2:
            wholeScreen();
            break;
        case KeyEvent::K3:
            split(Layout::Vertical);
            break;
        case KeyEvent::K4:
            split(Layout::Horizontal);
            break;
        case KeyEvent::KO:
            {
                auto openDialog = new OpenDialog(activeScreen_);
                connect(SIGNAL(openDialog, openFile), SLOT(this, openFile));
                tabs_.addTextBuffer(openDialog);
                break;
            }
        case KeyEvent::KS:
            save();
            break;
        case KeyEvent::KN:
            tabs_.addTextBuffer(new TextFile);
            break;
        case KeyEvent::KW:
            if (dynamic_cast<TextFile *>(tabs_.activeTextBuffer()) && tabs_.activeTextBuffer()->isModified())
            {
                if (!statusBar_.textBuffer())
                {
                    auto d = new Dialog(L"The file is modified. Do you want to save it before closing?");
                    statusBar_.setTextBuffer(d);
                    connect(SIGNAL(d, result), SLOT(this, closeActiveTextBuffer));
                }
            }
            else
                tabs_.closeActiveTextBuffer();
            break;
        case KeyEvent::KPageUp:
        case KeyEvent::KLeft:
            tabs_.switchToPrevTextBuffer();
            break;
        case KeyEvent::KPageDown:
        case KeyEvent::KRight:
            tabs_.switchToNextTextBuffer();
            break;
        case KeyEvent::KTab:
            switchToNextScreen();
            break;
        default:
            result1 = false;
        }
        break;
    case KeyEvent::MLAlt:
    case KeyEvent::MRAlt:
        switch (e.key())
        {
        case KeyEvent::KLeft:
            switchToPrevScreen();
            break;
        case KeyEvent::KRight:
            switchToNextScreen();
            break;
        default:
            result1 = false;
        }
        break;
    default:
        result1 = false;
    }

    bool result2 = true;
    if ((e.modifiers() & KeyEvent::MCtrl) != 0 && (e.modifiers() & KeyEvent::MShift) != 0)
    {
        switch (e.key())
        {
        case KeyEvent::KLeft:
            tabs_.moveTextBufferLeft();
            break;
        case KeyEvent::KRight:
            tabs_.moveTextBufferRight();
            break;
        default:
            result2 = false;
        }
    }
    else
        result2 = false;

    return result1 || result2;
}

void MainWindow::openFile(OpenDialog *sender, std::string fileName)
{
    tabs_.closeTextBuffer(sender);
    tabs_.addTextBuffer(new TextFile(fileName));
}

void MainWindow::saveAs(SaveDialog *sender, TextFile *textFile, std::string fileName)
{
    tabs_.closeTextBuffer(sender);
    tabs_.setActiveTextBuffer(textFile);
    textFile->saveAs(fileName);
}

void MainWindow::saveAndClose(SaveDialog *sender, TextFile *textFile, std::string fileName)
{
    tabs_.closeTextBuffer(sender);
    tabs_.closeTextBuffer(textFile);
    textFile->saveAs(fileName);
}

void MainWindow::closeActiveTextBuffer(Dialog::Answer value)
{
    auto d = statusBar_.textBuffer();
    Application::instance()->queueDelete(d);
    statusBar_.setTextBuffer(nullptr);
    if (auto textFile = dynamic_cast<TextFile *>(activeScreen_->textBuffer()))
    {
        switch (value)
        {
        case Dialog::Yes:
            if (textFile->fileName().empty())
            {
                auto saveDialog = new SaveDialog(activeScreen_, textFile);
                tabs_.addTextBuffer(saveDialog);
                activeScreen_->setCursor(0, 1);
                connect(SIGNAL(saveDialog, saveAs), SLOT(this, saveAndClose));
            }
            else
            {
                textFile->save();
                tabs_.closeActiveTextBuffer();
            }
            break;
        case Dialog::No:
            tabs_.closeActiveTextBuffer();
            break;
        case Dialog::Cancel:
            break;

        }
        tabs_.update();
    }
}

void MainWindow::save()
{
    if (auto textFile = dynamic_cast<TextFile *>(activeScreen_->textBuffer()))
    {
        if (textFile->fileName().empty())
        {
            auto saveDialog = new SaveDialog(activeScreen_, textFile);
            tabs_.addTextBuffer(saveDialog);
            activeScreen_->setCursor(0, 1);
            connect(SIGNAL(saveDialog, saveAs), SLOT(this, saveAs));
        }
        else
            textFile->save();
        tabs_.update();
    }
}

static void markForDeleteRecursively(Layoutable *value)
{
    if (auto layout = dynamic_cast<Layout *>(value))
    {
        auto children = layout->children();
        for (auto child: children)
        {
            markForDeleteRecursively(child);
            child->parentLayout()->removeLayoutable(child);
            Application::instance()->queueDelete(child);
        }
    }
}

void MainWindow::wholeScreen()
{
    markForDeleteRecursively(&screenLayout_);
    auto screen = activeScreen_;
    activeScreen_ = new Screen(this);
    activeScreen_->setStatusBar(&statusBar_);
    screenLayout_.addLayoutable(activeScreen_);
    activeScreen_->setTextBuffer(screen->textBuffer());
    activeScreen_->setFocus();
}

void MainWindow::split(Layout::Style style)
{
    auto layout = activeScreen_->parentLayout();
    layout->setStyle(style);
    auto l1 = new Layout(Layout::Vertical);
    auto l2 = new Layout(Layout::Vertical);
    layout->removeLayoutable(activeScreen_);
    layout->addLayoutable(l1);
    layout->addLayoutable(l2);
    l1->addLayoutable(activeScreen_);
    auto s2 = new Screen(this);
    s2->setStatusBar(&statusBar_);
    s2->setTextBuffer(activeScreen_->textBuffer());
    l2->addLayoutable(s2);
}

static std::vector<Screen *> getListOfScreens(Layoutable *l)
{
    std::vector<Screen *> res;
    if (auto screen = dynamic_cast<Screen *>(l))
        res.push_back(screen);
    else if (auto layout = dynamic_cast<Layout *>(l))
    {
        auto children = layout->children();
        for (Layoutable *child: children)
        {
            std::vector<Screen *> tmp = getListOfScreens(child);
            res.insert(end(res), begin(tmp), end(tmp));
        }
    }
    return res;
}

void MainWindow::switchToPrevScreen()
{
    std::vector<Screen *> list = getListOfScreens(&screenLayout_);
    auto iter = std::find(begin(list), end(list), activeScreen_);
    assert(iter != end(list));
    if (iter != begin(list))
        --iter;
    else
        iter = end(list) - 1;
    activeScreen_ = *iter;
    tabs_.setActiveTextBuffer(activeScreen_->textBuffer());
    activeScreen_->setFocus();
}

void MainWindow::switchToNextScreen()
{
    std::vector<Screen *> list = getListOfScreens(&screenLayout_);
    auto iter = std::find(begin(list), end(list), activeScreen_);
    assert(iter != end(list));
    if (iter + 1 != end(list))
        ++iter;
    else
        iter = begin(list);
    activeScreen_ = *iter;
    tabs_.setActiveTextBuffer(activeScreen_->textBuffer());
    activeScreen_->setFocus();
}

void MainWindow::setTextBuffer(BaseTextBuffer *textBuffer)
{
    activeScreen_->setTextBuffer(textBuffer);
}

static void internalDeleteTextBuffer(Layoutable *l, BaseTextBuffer *textBuffer)
{
    if (auto screen = dynamic_cast<Screen *>(l))
    {
        if (screen->textBuffer() == textBuffer)
            screen->setTextBuffer(nullptr);
    }
    else if (auto layout = dynamic_cast<Layout *>(l))
    {
        auto children = layout->children();
        for (Layoutable *child: children)
            internalDeleteTextBuffer(child, textBuffer);
    }
}

void MainWindow::deleteTextBuffer(BaseTextBuffer *textBuffer)
{
    internalDeleteTextBuffer(&screenLayout_, textBuffer);
}
<commit_msg>Implement #53 Don't close Open dialog automatically<commit_after>#include "main_window.hpp"
#include "key_event.hpp"
#include "open_dialog.hpp"
#include "save_dialog.hpp"
#include "text_file.hpp"
#include "dialog.hpp"
#include "application.hpp"
#include <algorithm>
#include <cassert>

MainWindow::MainWindow(Widget *parent):
    Widget(parent),
    activeScreen_(nullptr),
    layout_(Layout::Vertical),
    tabs_(this),
    statusBar_(this),
    screenLayout_(Layout::Vertical)
{
    activeScreen_ = new Screen(this);
    connect(SIGNAL(&tabs_, setTextBuffer), SLOT(this, setTextBuffer));
    connect(SIGNAL(&tabs_, deleteTextBuffer), SLOT(this, deleteTextBuffer));
    activeScreen_->setStatusBar(&statusBar_);
    setLayout(&layout_);
    layout_.addLayoutable(&tabs_);
    screenLayout_.addLayoutable(activeScreen_);
    layout_.addLayoutable(&screenLayout_);
    layout_.addLayoutable(&statusBar_);
    activeScreen_->setFocus();
}

bool MainWindow::keyPressEvent(KeyEvent &e)
{
    bool result1 = true;
    switch (e.modifiers())
    {
    case KeyEvent::MLCtrl:
    case KeyEvent::MRCtrl:
        switch (e.key())
        {
        case KeyEvent::K2:
            wholeScreen();
            break;
        case KeyEvent::K3:
            split(Layout::Vertical);
            break;
        case KeyEvent::K4:
            split(Layout::Horizontal);
            break;
        case KeyEvent::KO:
            {
                auto tmp = std::find_if(std::begin(tabs_.textBuffersList()),
                                        std::end(tabs_.textBuffersList()),
                                        [](BaseTextBuffer *x)
                                        {
                                            return dynamic_cast<OpenDialog *>(x);
                                        });
                if (tmp == std::end(tabs_.textBuffersList()))
                {
                    auto openDialog = new OpenDialog(activeScreen_);
                    connect(SIGNAL(openDialog, openFile), SLOT(this, openFile));
                    tabs_.addTextBuffer(openDialog);
                }
                else
                    tabs_.setActiveTextBuffer(*tmp);
                break;
            }
        case KeyEvent::KS:
            save();
            break;
        case KeyEvent::KN:
            tabs_.addTextBuffer(new TextFile);
            break;
        case KeyEvent::KW:
            if (dynamic_cast<TextFile *>(tabs_.activeTextBuffer()) && tabs_.activeTextBuffer()->isModified())
            {
                if (!statusBar_.textBuffer())
                {
                    auto d = new Dialog(L"The file is modified. Do you want to save it before closing?");
                    statusBar_.setTextBuffer(d);
                    connect(SIGNAL(d, result), SLOT(this, closeActiveTextBuffer));
                }
            }
            else
                tabs_.closeActiveTextBuffer();
            break;
        case KeyEvent::KPageUp:
        case KeyEvent::KLeft:
            tabs_.switchToPrevTextBuffer();
            break;
        case KeyEvent::KPageDown:
        case KeyEvent::KRight:
            tabs_.switchToNextTextBuffer();
            break;
        case KeyEvent::KTab:
            switchToNextScreen();
            break;
        default:
            result1 = false;
        }
        break;
    case KeyEvent::MLAlt:
    case KeyEvent::MRAlt:
        switch (e.key())
        {
        case KeyEvent::KLeft:
            switchToPrevScreen();
            break;
        case KeyEvent::KRight:
            switchToNextScreen();
            break;
        default:
            result1 = false;
        }
        break;
    default:
        result1 = false;
    }

    bool result2 = true;
    if ((e.modifiers() & KeyEvent::MCtrl) != 0 && (e.modifiers() & KeyEvent::MShift) != 0)
    {
        switch (e.key())
        {
        case KeyEvent::KLeft:
            tabs_.moveTextBufferLeft();
            break;
        case KeyEvent::KRight:
            tabs_.moveTextBufferRight();
            break;
        default:
            result2 = false;
        }
    }
    else
        result2 = false;

    return result1 || result2;
}

void MainWindow::openFile(OpenDialog *sender, std::string fileName)
{
    tabs_.addTextBuffer(new TextFile(fileName));
}

void MainWindow::saveAs(SaveDialog *sender, TextFile *textFile, std::string fileName)
{
    tabs_.closeTextBuffer(sender);
    tabs_.setActiveTextBuffer(textFile);
    textFile->saveAs(fileName);
}

void MainWindow::saveAndClose(SaveDialog *sender, TextFile *textFile, std::string fileName)
{
    tabs_.closeTextBuffer(sender);
    tabs_.closeTextBuffer(textFile);
    textFile->saveAs(fileName);
}

void MainWindow::closeActiveTextBuffer(Dialog::Answer value)
{
    auto d = statusBar_.textBuffer();
    Application::instance()->queueDelete(d);
    statusBar_.setTextBuffer(nullptr);
    if (auto textFile = dynamic_cast<TextFile *>(activeScreen_->textBuffer()))
    {
        switch (value)
        {
        case Dialog::Yes:
            if (textFile->fileName().empty())
            {
                auto saveDialog = new SaveDialog(activeScreen_, textFile);
                tabs_.addTextBuffer(saveDialog);
                activeScreen_->setCursor(0, 1);
                connect(SIGNAL(saveDialog, saveAs), SLOT(this, saveAndClose));
            }
            else
            {
                textFile->save();
                tabs_.closeActiveTextBuffer();
            }
            break;
        case Dialog::No:
            tabs_.closeActiveTextBuffer();
            break;
        case Dialog::Cancel:
            break;

        }
        tabs_.update();
    }
}

void MainWindow::save()
{
    if (auto textFile = dynamic_cast<TextFile *>(activeScreen_->textBuffer()))
    {
        if (textFile->fileName().empty())
        {
            auto saveDialog = new SaveDialog(activeScreen_, textFile);
            tabs_.addTextBuffer(saveDialog);
            activeScreen_->setCursor(0, 1);
            connect(SIGNAL(saveDialog, saveAs), SLOT(this, saveAs));
        }
        else
            textFile->save();
        tabs_.update();
    }
}

static void markForDeleteRecursively(Layoutable *value)
{
    if (auto layout = dynamic_cast<Layout *>(value))
    {
        auto children = layout->children();
        for (auto child: children)
        {
            markForDeleteRecursively(child);
            child->parentLayout()->removeLayoutable(child);
            Application::instance()->queueDelete(child);
        }
    }
}

void MainWindow::wholeScreen()
{
    markForDeleteRecursively(&screenLayout_);
    auto screen = activeScreen_;
    activeScreen_ = new Screen(this);
    activeScreen_->setStatusBar(&statusBar_);
    screenLayout_.addLayoutable(activeScreen_);
    activeScreen_->setTextBuffer(screen->textBuffer());
    activeScreen_->setFocus();
}

void MainWindow::split(Layout::Style style)
{
    auto layout = activeScreen_->parentLayout();
    layout->setStyle(style);
    auto l1 = new Layout(Layout::Vertical);
    auto l2 = new Layout(Layout::Vertical);
    layout->removeLayoutable(activeScreen_);
    layout->addLayoutable(l1);
    layout->addLayoutable(l2);
    l1->addLayoutable(activeScreen_);
    auto s2 = new Screen(this);
    s2->setStatusBar(&statusBar_);
    s2->setTextBuffer(activeScreen_->textBuffer());
    l2->addLayoutable(s2);
}

static std::vector<Screen *> getListOfScreens(Layoutable *l)
{
    std::vector<Screen *> res;
    if (auto screen = dynamic_cast<Screen *>(l))
        res.push_back(screen);
    else if (auto layout = dynamic_cast<Layout *>(l))
    {
        auto children = layout->children();
        for (Layoutable *child: children)
        {
            std::vector<Screen *> tmp = getListOfScreens(child);
            res.insert(end(res), begin(tmp), end(tmp));
        }
    }
    return res;
}

void MainWindow::switchToPrevScreen()
{
    std::vector<Screen *> list = getListOfScreens(&screenLayout_);
    auto iter = std::find(begin(list), end(list), activeScreen_);
    assert(iter != end(list));
    if (iter != begin(list))
        --iter;
    else
        iter = end(list) - 1;
    activeScreen_ = *iter;
    tabs_.setActiveTextBuffer(activeScreen_->textBuffer());
    activeScreen_->setFocus();
}

void MainWindow::switchToNextScreen()
{
    std::vector<Screen *> list = getListOfScreens(&screenLayout_);
    auto iter = std::find(begin(list), end(list), activeScreen_);
    assert(iter != end(list));
    if (iter + 1 != end(list))
        ++iter;
    else
        iter = begin(list);
    activeScreen_ = *iter;
    tabs_.setActiveTextBuffer(activeScreen_->textBuffer());
    activeScreen_->setFocus();
}

void MainWindow::setTextBuffer(BaseTextBuffer *textBuffer)
{
    activeScreen_->setTextBuffer(textBuffer);
}

static void internalDeleteTextBuffer(Layoutable *l, BaseTextBuffer *textBuffer)
{
    if (auto screen = dynamic_cast<Screen *>(l))
    {
        if (screen->textBuffer() == textBuffer)
            screen->setTextBuffer(nullptr);
    }
    else if (auto layout = dynamic_cast<Layout *>(l))
    {
        auto children = layout->children();
        for (Layoutable *child: children)
            internalDeleteTextBuffer(child, textBuffer);
    }
}

void MainWindow::deleteTextBuffer(BaseTextBuffer *textBuffer)
{
    internalDeleteTextBuffer(&screenLayout_, textBuffer);
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2014-2019 AscEmu Team <http://www.ascemu.org>
This file is released under the MIT license. See README-MIT for more information.
*/

#include "StdAfx.h"
#include "Singleton.h"
#include "GameEventMgr.h"
#include "Log.hpp"
#include "Server/World.h"
#include "Server/World.Legacy.h"
#include "Server/MainServerDefines.h"
#include "GameEvent.h"
#include "Storage/MySQLDataStore.hpp"
#include "CrashHandler.h"

initialiseSingleton(GameEventMgr);
initialiseSingleton(GameEventMgr::GameEventMgrThread);

GameEventMgr::GameEventMgr()
{
    mGameEvents.clear();
}
GameEventMgr::~GameEventMgr()
{

}

GameEvent* GameEventMgr::GetEventById(uint32 pEventId)
{
    auto rEvent = mGameEvents.find(pEventId);
    if (rEvent == mGameEvents.end())
        return nullptr;
    else
        return rEvent->second;
}

void GameEventMgr::StartArenaEvents()
{
    for (auto i = 57; i <= 60; ++i)
    {
        auto gameEvent = GetEventById(i);
        if (gameEvent == nullptr)
        {
            LOG_ERROR("Missing arena event (id: %u)", i);
            continue;
        }

        if (i - 52 == worldConfig.arena.arenaSeason && worldConfig.arena.arenaProgress == 1)
            gameEvent->SetState(GAMEEVENT_ACTIVE_FORCED);
        else
            gameEvent->SetState(GAMEEVENT_INACTIVE_FORCED);
    }
}

void GameEventMgr::LoadFromDB()
{
    // Clean event_saves from CharacterDB
    LogNotice("GameEventMgr : Start cleaning event_save");
    {
        const char* cleanEventSaveQuery = "DELETE FROM event_save WHERE state<>4";
        CharacterDatabase.Execute(cleanEventSaveQuery);
    }
    // Loading event_properties
    {
        QueryResult* result = WorldDatabase.Query("SELECT entry, UNIX_TIMESTAMP(start_time), UNIX_TIMESTAMP(end_time), occurence, "
                                          "length, holiday, description, world_event, announce "
                                          "FROM event_properties WHERE entry > 0 AND min_build <= %u AND max_build >= %u", getAEVersion(), getAEVersion());
        if (!result)
        {
            //mGameEvent.clear();
            LOG_ERROR("event_properties can not be read or does not include any version specific events!");
            return;
        }

        uint32 pCount = 0;
        do
        {
            Field* field = result->Fetch();

            EventNamesQueryResult dbResult;
            dbResult.entry = field[0].GetUInt32();
            dbResult.start_time = field[1].GetUInt32();
            dbResult.end_time = field[2].GetUInt32();
            dbResult.occurence = field[3].GetUInt32();
            dbResult.length = field[4].GetUInt32();
            dbResult.holiday_id = HolidayIds(field[5].GetUInt32());
            dbResult.description = field[6].GetString();
            dbResult.world_event = GameEventState(field[7].GetUInt8());
            dbResult.announce = field[8].GetUInt8();

            GameEvent gameEvent = GameEvent(dbResult);

            //if (gameEvent.isValid())
            //{
                mGameEvents.insert(std::make_pair(dbResult.entry, new GameEvent(dbResult)));
                LogDebugFlag(LF_DB_TABLES, "GameEventMgr : %s, Entry: %u, State: %u, Holiday: %u loaded", dbResult.description.c_str(), dbResult.entry, dbResult.world_event, dbResult.holiday_id);
                ++pCount;
            //}
            //else
            //{
            //    LOG_DEBUG("%s game event Entry: %u isn't a world event and has length = 0, thus it can't be used.", dbResult.description.c_str(), dbResult.entry);
            //}
        } while (result->NextRow());
        delete result;
        LogDetail("GameEventMgr : %u events loaded from table event_properties", pCount);
    }
    // Loading event_saves from CharacterDB
    LogNotice("GameEventMgr : Start loading event_save");
    {
        const char* loadEventSaveQuery = "SELECT event_entry, state, next_start FROM event_save";
        bool success = false;
        QueryResult* result = CharacterDatabase.Query(&success, loadEventSaveQuery);

        if (!success)
        {
            LOG_ERROR("Query failed: %s", loadEventSaveQuery);
            return;
        }

        uint32 pCount = 0;
        if (result)
        {
            do
            {
                Field* field = result->Fetch();
                uint32 event_id = field[0].GetUInt8();

                auto gameEvent = GetEventById(event_id);
                if (gameEvent == nullptr)
                {
                    LOG_ERROR("Could not find event for event_save entry %u", event_id);
                    continue;
                }

                gameEvent->state = (GameEventState)(field[1].GetUInt8());
                gameEvent->nextstart = time_t(field[2].GetUInt32());

                ++pCount;

            } while (result->NextRow());
            delete result;
        }

        LogDetail("GameEventMgr : Loaded %u saved events loaded from table event_saves", pCount);
    }
    // Loading event_creature from WorldDB
    LogNotice("GameEventMgr : Start loading game event creature spawns");
    {
        const char* loadEventCreatureSpawnsQuery = "SELECT id, entry, map, position_x, position_y, position_z, \
                                                    orientation, movetype, displayid, faction, flags, bytes0, bytes1, bytes2, \
                                                    emote_state, npc_respawn_link, channel_spell, channel_target_sqlid, \
                                                    channel_target_sqlid_creature, standstate, death_state, mountdisplayid, \
                                                    slot1item, slot2item, slot3item, CanFly, phase, waypoint_group, event_entry \
                                                    FROM creature_spawns WHERE min_build <= %u AND max_build >= %u AND event_entry > 0";
        bool success = false;
        QueryResult* result = WorldDatabase.Query(&success, loadEventCreatureSpawnsQuery, VERSION_STRING, VERSION_STRING);
        if (!success)
        {
            LOG_ERROR("Query failed: %s", loadEventCreatureSpawnsQuery);
            return;
        }

        uint32 pCount = 0;
        if (result)
        {
            do
            {
                Field* field = result->Fetch();

                uint32 event_id = field[28].GetUInt32();

                auto gameEvent = GetEventById(event_id);
                if (gameEvent == nullptr)
                {
                    LOG_ERROR("Could not find event for creature_spawns entry %u", event_id);
                    continue;
                }

                EventCreatureSpawnsQueryResult dbResult;
                dbResult.event_entry = field[28].GetUInt32();
                dbResult.id = field[0].GetUInt32();
                dbResult.entry = field[1].GetUInt32();
                auto creature_properties = sMySQLStore.getCreatureProperties(dbResult.entry);
                if (creature_properties == nullptr)
                {
                    LOG_ERROR("Could not create CreatureSpawn for invalid entry %u (missing in table creature_properties)", dbResult.entry);
                    continue;
                }
                dbResult.map_id = field[2].GetUInt16();
                dbResult.position_x = field[3].GetFloat();
                dbResult.position_y = field[4].GetFloat();
                dbResult.position_z = field[5].GetFloat();
                dbResult.orientation = field[6].GetFloat();
                dbResult.movetype = field[7].GetUInt8();
                dbResult.displayid = field[8].GetUInt32();
                dbResult.faction = field[9].GetUInt32();
                dbResult.flags = field[10].GetUInt32();
                dbResult.bytes0 = field[11].GetUInt32();
                dbResult.bytes1 = field[12].GetUInt32();
                dbResult.bytes2 = field[13].GetUInt32();
                dbResult.emote_state = field[14].GetUInt16();
                dbResult.npc_respawn_link = field[15].GetUInt32();
                dbResult.channel_spell = field[16].GetUInt32();
                dbResult.channel_target_sqlid = field[17].GetUInt32();
                dbResult.channel_target_sqlid_creature = field[18].GetUInt32();
                dbResult.standstate = field[19].GetUInt8();
                dbResult.death_state = field[20].GetUInt8();
                dbResult.mountdisplayid = field[21].GetUInt32();
                dbResult.slot1item = field[22].GetUInt32();
                dbResult.slot2item = field[23].GetUInt32();
                dbResult.slot3item = field[24].GetUInt32();
                dbResult.CanFly = field[25].GetUInt16();
                dbResult.phase = field[26].GetUInt32();
                dbResult.waypoint_group = field[27].GetUInt32();

                gameEvent->npc_data.push_back(dbResult);

                ++pCount;

                //mNPCGuidList.insert(NPCGuidList::value_type(event_id, id));

            } while (result->NextRow());
            delete result;
        }
        LogDetail("GameEventMgr : %u creature spawns for %u events from table event_creature_spawns loaded.", pCount, mGameEvents.size());
    }
    // Loading event_gameobject from WorldDB
    LogNotice("GameEventMgr : Start loading game event gameobject spawns");
    {
        const char* loadEventGameobjectSpawnsQuery = "SELECT id, entry, map, position_x, position_y, \
                                                      position_z, facing, orientation1, orientation2, orientation3, \
                                                      orientation4, state, flags, faction, scale, respawnNpcLink, phase, \
                                                      overrides, event_entry FROM gameobject_spawns WHERE min_build <= %u AND max_build >= %u AND event_entry > 0;";
        bool success = false;
        QueryResult* result = WorldDatabase.Query(&success, loadEventGameobjectSpawnsQuery, VERSION_STRING, VERSION_STRING);
        if (!success)
        {
            LOG_ERROR("Query failed: %s", loadEventGameobjectSpawnsQuery);
            return;
        }

        uint32 pCount = 0;
        if (result)
        {
            do
            {
                Field* field = result->Fetch();
                uint32 event_id = field[18].GetUInt32();

                auto gameEvent = GetEventById(event_id);
                if (gameEvent == nullptr)
                {
                    LOG_ERROR("ould not find event for gameobject_spawns entry %u", event_id);
                    continue;
                }

                EventGameObjectSpawnsQueryResult dbResult;
                dbResult.event_entry = field[18].GetUInt32();
                dbResult.id = field[0].GetUInt32();
                dbResult.entry = field[1].GetUInt32();
                auto gameobject_info = sMySQLStore.getGameObjectProperties(dbResult.entry);
                if (gameobject_info == nullptr)
                {
                    LOG_ERROR("Could not create GameobjectSpawn for invalid entry %u (missing in table gameobject_properties)", dbResult.entry);
                    continue;
                }
                dbResult.map_id = field[2].GetUInt32();
                dbResult.position_x = field[3].GetFloat();
                dbResult.position_y = field[4].GetFloat();
                dbResult.position_z = field[5].GetFloat();
                dbResult.facing = field[6].GetFloat();
                dbResult.orientation1 = field[7].GetFloat();
                dbResult.orientation2 = field[8].GetFloat();
                dbResult.orientation3 = field[9].GetFloat();
                dbResult.orientation4 = field[10].GetFloat();
                dbResult.state = field[11].GetUInt32();
                dbResult.flags = field[12].GetUInt32();
                dbResult.faction = field[13].GetUInt32();
                dbResult.scale = field[14].GetFloat();
                dbResult.stateNpcLink = field[15].GetUInt32();
                dbResult.phase = field[16].GetUInt32();
                dbResult.overrides = field[17].GetUInt32();

                gameEvent->gameobject_data.push_back(dbResult);

                ++pCount;

                //mGOBGuidList.insert(GOBGuidList::value_type(event_id, id));

            } while (result->NextRow());
            delete result;
        }
        LogDetail("GameEventMgr : %u gameobject spawns for %u events from table gameobject_spawns loaded.", pCount, mGameEvents.size());
    }

    StartArenaEvents();
}

GameEventMgr::GameEventMgrThread::GameEventMgrThread()
{
    m_reloadThread = std::make_unique<AscEmu::Threading::AEThread>("ReloadAccounts", [this](AscEmu::Threading::AEThread& thread) { this->Update(); }, std::chrono::seconds(1));
}

GameEventMgr::GameEventMgrThread::~GameEventMgrThread()
{
    LogNotice("GameEventMgrThread : Stop Manager...");
    m_reloadThread->killAndJoin();
}

void GameEventMgr::GameEventMgrThread::Update()
{
    //LogNotice("GameEventMgr : Tick!");
    auto now = time(0);

    for (auto gameEventPair : sGameEventMgr.mGameEvents)
    {
        GameEvent* gameEvent = gameEventPair.second;

        // Don't alter manual events
        if (!gameEvent->isValid())
            continue;

        auto startTime = time_t(gameEvent->start);
        if (startTime < now && now < gameEvent->end)
        {
            if ((now - startTime) % (gameEvent->occurence * 60) < gameEvent->length * 60)
            {
                // Event should start
                if (gameEvent->state != GAMEEVENT_INACTIVE_FORCED)
                {
                    gameEvent->StartEvent();
                    continue;
                }
            }
            continue;
        }

        // Event should stop
        if (gameEvent->state != GAMEEVENT_ACTIVE_FORCED)
        {
            gameEvent->StopEvent();
        }
    }
}
<commit_msg>Corrected ThreadName<commit_after>/*
Copyright (c) 2014-2019 AscEmu Team <http://www.ascemu.org>
This file is released under the MIT license. See README-MIT for more information.
*/

#include "StdAfx.h"
#include "Singleton.h"
#include "GameEventMgr.h"
#include "Log.hpp"
#include "Server/World.h"
#include "Server/World.Legacy.h"
#include "Server/MainServerDefines.h"
#include "GameEvent.h"
#include "Storage/MySQLDataStore.hpp"
#include "CrashHandler.h"

initialiseSingleton(GameEventMgr);
initialiseSingleton(GameEventMgr::GameEventMgrThread);

GameEventMgr::GameEventMgr()
{
    mGameEvents.clear();
}
GameEventMgr::~GameEventMgr()
{

}

GameEvent* GameEventMgr::GetEventById(uint32 pEventId)
{
    auto rEvent = mGameEvents.find(pEventId);
    if (rEvent == mGameEvents.end())
        return nullptr;
    else
        return rEvent->second;
}

void GameEventMgr::StartArenaEvents()
{
    for (auto i = 57; i <= 60; ++i)
    {
        auto gameEvent = GetEventById(i);
        if (gameEvent == nullptr)
        {
            LOG_ERROR("Missing arena event (id: %u)", i);
            continue;
        }

        if (i - 52 == worldConfig.arena.arenaSeason && worldConfig.arena.arenaProgress == 1)
            gameEvent->SetState(GAMEEVENT_ACTIVE_FORCED);
        else
            gameEvent->SetState(GAMEEVENT_INACTIVE_FORCED);
    }
}

void GameEventMgr::LoadFromDB()
{
    // Clean event_saves from CharacterDB
    LogNotice("GameEventMgr : Start cleaning event_save");
    {
        const char* cleanEventSaveQuery = "DELETE FROM event_save WHERE state<>4";
        CharacterDatabase.Execute(cleanEventSaveQuery);
    }
    // Loading event_properties
    {
        QueryResult* result = WorldDatabase.Query("SELECT entry, UNIX_TIMESTAMP(start_time), UNIX_TIMESTAMP(end_time), occurence, "
                                          "length, holiday, description, world_event, announce "
                                          "FROM event_properties WHERE entry > 0 AND min_build <= %u AND max_build >= %u", getAEVersion(), getAEVersion());
        if (!result)
        {
            //mGameEvent.clear();
            LOG_ERROR("event_properties can not be read or does not include any version specific events!");
            return;
        }

        uint32 pCount = 0;
        do
        {
            Field* field = result->Fetch();

            EventNamesQueryResult dbResult;
            dbResult.entry = field[0].GetUInt32();
            dbResult.start_time = field[1].GetUInt32();
            dbResult.end_time = field[2].GetUInt32();
            dbResult.occurence = field[3].GetUInt32();
            dbResult.length = field[4].GetUInt32();
            dbResult.holiday_id = HolidayIds(field[5].GetUInt32());
            dbResult.description = field[6].GetString();
            dbResult.world_event = GameEventState(field[7].GetUInt8());
            dbResult.announce = field[8].GetUInt8();

            GameEvent gameEvent = GameEvent(dbResult);

            //if (gameEvent.isValid())
            //{
                mGameEvents.insert(std::make_pair(dbResult.entry, new GameEvent(dbResult)));
                LogDebugFlag(LF_DB_TABLES, "GameEventMgr : %s, Entry: %u, State: %u, Holiday: %u loaded", dbResult.description.c_str(), dbResult.entry, dbResult.world_event, dbResult.holiday_id);
                ++pCount;
            //}
            //else
            //{
            //    LOG_DEBUG("%s game event Entry: %u isn't a world event and has length = 0, thus it can't be used.", dbResult.description.c_str(), dbResult.entry);
            //}
        } while (result->NextRow());
        delete result;
        LogDetail("GameEventMgr : %u events loaded from table event_properties", pCount);
    }
    // Loading event_saves from CharacterDB
    LogNotice("GameEventMgr : Start loading event_save");
    {
        const char* loadEventSaveQuery = "SELECT event_entry, state, next_start FROM event_save";
        bool success = false;
        QueryResult* result = CharacterDatabase.Query(&success, loadEventSaveQuery);

        if (!success)
        {
            LOG_ERROR("Query failed: %s", loadEventSaveQuery);
            return;
        }

        uint32 pCount = 0;
        if (result)
        {
            do
            {
                Field* field = result->Fetch();
                uint32 event_id = field[0].GetUInt8();

                auto gameEvent = GetEventById(event_id);
                if (gameEvent == nullptr)
                {
                    LOG_ERROR("Could not find event for event_save entry %u", event_id);
                    continue;
                }

                gameEvent->state = (GameEventState)(field[1].GetUInt8());
                gameEvent->nextstart = time_t(field[2].GetUInt32());

                ++pCount;

            } while (result->NextRow());
            delete result;
        }

        LogDetail("GameEventMgr : Loaded %u saved events loaded from table event_saves", pCount);
    }
    // Loading event_creature from WorldDB
    LogNotice("GameEventMgr : Start loading game event creature spawns");
    {
        const char* loadEventCreatureSpawnsQuery = "SELECT id, entry, map, position_x, position_y, position_z, \
                                                    orientation, movetype, displayid, faction, flags, bytes0, bytes1, bytes2, \
                                                    emote_state, npc_respawn_link, channel_spell, channel_target_sqlid, \
                                                    channel_target_sqlid_creature, standstate, death_state, mountdisplayid, \
                                                    slot1item, slot2item, slot3item, CanFly, phase, waypoint_group, event_entry \
                                                    FROM creature_spawns WHERE min_build <= %u AND max_build >= %u AND event_entry > 0";
        bool success = false;
        QueryResult* result = WorldDatabase.Query(&success, loadEventCreatureSpawnsQuery, VERSION_STRING, VERSION_STRING);
        if (!success)
        {
            LOG_ERROR("Query failed: %s", loadEventCreatureSpawnsQuery);
            return;
        }

        uint32 pCount = 0;
        if (result)
        {
            do
            {
                Field* field = result->Fetch();

                uint32 event_id = field[28].GetUInt32();

                auto gameEvent = GetEventById(event_id);
                if (gameEvent == nullptr)
                {
                    LOG_ERROR("Could not find event for creature_spawns entry %u", event_id);
                    continue;
                }

                EventCreatureSpawnsQueryResult dbResult;
                dbResult.event_entry = field[28].GetUInt32();
                dbResult.id = field[0].GetUInt32();
                dbResult.entry = field[1].GetUInt32();
                auto creature_properties = sMySQLStore.getCreatureProperties(dbResult.entry);
                if (creature_properties == nullptr)
                {
                    LOG_ERROR("Could not create CreatureSpawn for invalid entry %u (missing in table creature_properties)", dbResult.entry);
                    continue;
                }
                dbResult.map_id = field[2].GetUInt16();
                dbResult.position_x = field[3].GetFloat();
                dbResult.position_y = field[4].GetFloat();
                dbResult.position_z = field[5].GetFloat();
                dbResult.orientation = field[6].GetFloat();
                dbResult.movetype = field[7].GetUInt8();
                dbResult.displayid = field[8].GetUInt32();
                dbResult.faction = field[9].GetUInt32();
                dbResult.flags = field[10].GetUInt32();
                dbResult.bytes0 = field[11].GetUInt32();
                dbResult.bytes1 = field[12].GetUInt32();
                dbResult.bytes2 = field[13].GetUInt32();
                dbResult.emote_state = field[14].GetUInt16();
                dbResult.npc_respawn_link = field[15].GetUInt32();
                dbResult.channel_spell = field[16].GetUInt32();
                dbResult.channel_target_sqlid = field[17].GetUInt32();
                dbResult.channel_target_sqlid_creature = field[18].GetUInt32();
                dbResult.standstate = field[19].GetUInt8();
                dbResult.death_state = field[20].GetUInt8();
                dbResult.mountdisplayid = field[21].GetUInt32();
                dbResult.slot1item = field[22].GetUInt32();
                dbResult.slot2item = field[23].GetUInt32();
                dbResult.slot3item = field[24].GetUInt32();
                dbResult.CanFly = field[25].GetUInt16();
                dbResult.phase = field[26].GetUInt32();
                dbResult.waypoint_group = field[27].GetUInt32();

                gameEvent->npc_data.push_back(dbResult);

                ++pCount;

                //mNPCGuidList.insert(NPCGuidList::value_type(event_id, id));

            } while (result->NextRow());
            delete result;
        }
        LogDetail("GameEventMgr : %u creature spawns for %u events from table event_creature_spawns loaded.", pCount, mGameEvents.size());
    }
    // Loading event_gameobject from WorldDB
    LogNotice("GameEventMgr : Start loading game event gameobject spawns");
    {
        const char* loadEventGameobjectSpawnsQuery = "SELECT id, entry, map, position_x, position_y, \
                                                      position_z, facing, orientation1, orientation2, orientation3, \
                                                      orientation4, state, flags, faction, scale, respawnNpcLink, phase, \
                                                      overrides, event_entry FROM gameobject_spawns WHERE min_build <= %u AND max_build >= %u AND event_entry > 0;";
        bool success = false;
        QueryResult* result = WorldDatabase.Query(&success, loadEventGameobjectSpawnsQuery, VERSION_STRING, VERSION_STRING);
        if (!success)
        {
            LOG_ERROR("Query failed: %s", loadEventGameobjectSpawnsQuery);
            return;
        }

        uint32 pCount = 0;
        if (result)
        {
            do
            {
                Field* field = result->Fetch();
                uint32 event_id = field[18].GetUInt32();

                auto gameEvent = GetEventById(event_id);
                if (gameEvent == nullptr)
                {
                    LOG_ERROR("ould not find event for gameobject_spawns entry %u", event_id);
                    continue;
                }

                EventGameObjectSpawnsQueryResult dbResult;
                dbResult.event_entry = field[18].GetUInt32();
                dbResult.id = field[0].GetUInt32();
                dbResult.entry = field[1].GetUInt32();
                auto gameobject_info = sMySQLStore.getGameObjectProperties(dbResult.entry);
                if (gameobject_info == nullptr)
                {
                    LOG_ERROR("Could not create GameobjectSpawn for invalid entry %u (missing in table gameobject_properties)", dbResult.entry);
                    continue;
                }
                dbResult.map_id = field[2].GetUInt32();
                dbResult.position_x = field[3].GetFloat();
                dbResult.position_y = field[4].GetFloat();
                dbResult.position_z = field[5].GetFloat();
                dbResult.facing = field[6].GetFloat();
                dbResult.orientation1 = field[7].GetFloat();
                dbResult.orientation2 = field[8].GetFloat();
                dbResult.orientation3 = field[9].GetFloat();
                dbResult.orientation4 = field[10].GetFloat();
                dbResult.state = field[11].GetUInt32();
                dbResult.flags = field[12].GetUInt32();
                dbResult.faction = field[13].GetUInt32();
                dbResult.scale = field[14].GetFloat();
                dbResult.stateNpcLink = field[15].GetUInt32();
                dbResult.phase = field[16].GetUInt32();
                dbResult.overrides = field[17].GetUInt32();

                gameEvent->gameobject_data.push_back(dbResult);

                ++pCount;

                //mGOBGuidList.insert(GOBGuidList::value_type(event_id, id));

            } while (result->NextRow());
            delete result;
        }
        LogDetail("GameEventMgr : %u gameobject spawns for %u events from table gameobject_spawns loaded.", pCount, mGameEvents.size());
    }

    StartArenaEvents();
}

GameEventMgr::GameEventMgrThread::GameEventMgrThread()
{
    m_reloadThread = std::make_unique<AscEmu::Threading::AEThread>("UpdateGameEvents", [this](AscEmu::Threading::AEThread& thread) { this->Update(); }, std::chrono::seconds(1));
}

GameEventMgr::GameEventMgrThread::~GameEventMgrThread()
{
    LogNotice("GameEventMgrThread : Stop Manager...");
    m_reloadThread->killAndJoin();
}

void GameEventMgr::GameEventMgrThread::Update()
{
    //LogNotice("GameEventMgr : Tick!");
    auto now = time(0);

    for (auto gameEventPair : sGameEventMgr.mGameEvents)
    {
        GameEvent* gameEvent = gameEventPair.second;

        // Don't alter manual events
        if (!gameEvent->isValid())
            continue;

        auto startTime = time_t(gameEvent->start);
        if (startTime < now && now < gameEvent->end)
        {
            if ((now - startTime) % (gameEvent->occurence * 60) < gameEvent->length * 60)
            {
                // Event should start
                if (gameEvent->state != GAMEEVENT_INACTIVE_FORCED)
                {
                    gameEvent->StartEvent();
                    continue;
                }
            }
            continue;
        }

        // Event should stop
        if (gameEvent->state != GAMEEVENT_ACTIVE_FORCED)
        {
            gameEvent->StopEvent();
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 Open Source Robotics Foundation, 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 <memory>
#include <string>
#include <vector>

#include "class_loader/class_loader.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_components/node_factory.hpp"

#define LINKTIME_COMPOSITION_LOGGER_NAME "linktime_composition"

int main(int argc, char * argv[])
{
  // Force flush of the stdout buffer.
  setvbuf(stdout, NULL, _IONBF, BUFSIZ);

  rclcpp::init(argc, argv);
  rclcpp::Logger logger = rclcpp::get_logger(LINKTIME_COMPOSITION_LOGGER_NAME);
  rclcpp::executors::SingleThreadedExecutor exec;
  rclcpp::NodeOptions options;
  std::vector<class_loader::ClassLoader *> loaders;
  std::vector<rclcpp_components::NodeInstanceWrapper> node_wrappers;

  std::vector<std::string> libraries = {
    // all classes from libraries linked by the linker (rather then dlopen)
    // are registered under the library_path ""
    "",
  };
  for (auto library : libraries) {
    RCLCPP_INFO(logger, "Load library %s", library.c_str());
    auto loader = new class_loader::ClassLoader(library);
    auto classes = loader->getAvailableClasses<rclcpp_components::NodeFactory>();
    for (auto clazz : classes) {
      RCLCPP_INFO(logger, "Instantiate class %s", clazz.c_str());
      auto node_factory = loader->createInstance<rclcpp_components::NodeFactory>(clazz);
      auto wrapper = node_factory->create_node_instance(options);
      auto node = wrapper.get_node_base_interface();
      node_wrappers.push_back(wrapper);
      exec.add_node(node);
    }
    loaders.push_back(loader);
  }

  exec.spin();

  for (auto wrapper : node_wrappers) {
    exec.remove_node(wrapper.get_node_base_interface());
  }
  node_wrappers.clear();

  rclcpp::shutdown();

  return 0;
}
<commit_msg>Fix leak(#480) (#481)<commit_after>// Copyright 2016 Open Source Robotics Foundation, 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 <memory>
#include <string>
#include <vector>
#include <utility>

#include "class_loader/class_loader.hpp"
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_components/node_factory.hpp"

#define LINKTIME_COMPOSITION_LOGGER_NAME "linktime_composition"

int main(int argc, char * argv[])
{
  // Force flush of the stdout buffer.
  setvbuf(stdout, NULL, _IONBF, BUFSIZ);

  rclcpp::init(argc, argv);
  rclcpp::Logger logger = rclcpp::get_logger(LINKTIME_COMPOSITION_LOGGER_NAME);
  rclcpp::executors::SingleThreadedExecutor exec;
  rclcpp::NodeOptions options;
  std::vector<std::unique_ptr<class_loader::ClassLoader>> loaders;
  std::vector<rclcpp_components::NodeInstanceWrapper> node_wrappers;

  std::vector<std::string> libraries = {
    // all classes from libraries linked by the linker (rather then dlopen)
    // are registered under the library_path ""
    "",
  };
  for (auto library : libraries) {
    RCLCPP_INFO(logger, "Load library %s", library.c_str());
    auto loader = std::make_unique<class_loader::ClassLoader>(library);
    auto classes = loader->getAvailableClasses<rclcpp_components::NodeFactory>();
    for (auto clazz : classes) {
      RCLCPP_INFO(logger, "Instantiate class %s", clazz.c_str());
      auto node_factory = loader->createInstance<rclcpp_components::NodeFactory>(clazz);
      auto wrapper = node_factory->create_node_instance(options);
      auto node = wrapper.get_node_base_interface();
      node_wrappers.push_back(wrapper);
      exec.add_node(node);
    }
    loaders.push_back(std::move(loader));
  }

  exec.spin();

  for (auto wrapper : node_wrappers) {
    exec.remove_node(wrapper.get_node_base_interface());
  }
  node_wrappers.clear();

  rclcpp::shutdown();

  return 0;
}
<|endoftext|>


<commit_before>/*
 * This file is a part of Xpiks - cross platform application for
 * keywording and uploading images for microstocks
 * Copyright (C) 2014-2016 Taras Kushnir <kushnirTV@gmail.com>
 *
 * Xpiks is distributed under the GNU General Public License, version 3.0
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "remoteconfig.h"

namespace Helpers {
    RemoteConfig::RemoteConfig() {
        m_NetworkManager = new QNetworkAccessManager();

        QObject::connect(m_NetworkManager, SIGNAL(finished(QNetworkReply*)),
                         this, SLOT(replyReceived(QNetworkReply*)));
    }

    RemoteConfig::~RemoteConfig() {
        m_NetworkManager->deleteLater();
    }

    void RemoteConfig::requestInitConfig(const QString &configUrl) {
        m_ConfigUrl = configUrl;

        LOG_DEBUG << m_ConfigUrl;

        QUrl url;
        url.setUrl(m_ConfigUrl);

        QNetworkRequest request(url);
        QNetworkReply *reply = m_NetworkManager->get(request);
        Q_UNUSED(reply);
    }

    void RemoteConfig::replyReceived(QNetworkReply *networkReply) {
        LOG_DEBUG << "#";

        if (networkReply->error() == QNetworkReply::NoError) {
            QJsonParseError error;
            m_Config = QJsonDocument::fromJson(networkReply->readAll(), &error);

            if (error.error == QJsonParseError::NoError) {
                emit configArrived();
            } else {
                LOG_WARNING << "Failed to parse remote json" << error.errorString();
            }
        } else {
            LOG_WARNING << "Config download failed:" << networkReply->errorString();
        }

        networkReply->deleteLater();
    }
}
<commit_msg>Logging for integration tests for remote configs<commit_after>/*
 * This file is a part of Xpiks - cross platform application for
 * keywording and uploading images for microstocks
 * Copyright (C) 2014-2016 Taras Kushnir <kushnirTV@gmail.com>
 *
 * Xpiks is distributed under the GNU General Public License, version 3.0
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "remoteconfig.h"
#include "../Common/defines.h"

namespace Helpers {
    RemoteConfig::RemoteConfig() {
        m_NetworkManager = new QNetworkAccessManager();

        QObject::connect(m_NetworkManager, SIGNAL(finished(QNetworkReply*)),
                         this, SLOT(replyReceived(QNetworkReply*)));
    }

    RemoteConfig::~RemoteConfig() {
        m_NetworkManager->deleteLater();
    }

    void RemoteConfig::requestInitConfig(const QString &configUrl) {
        m_ConfigUrl = configUrl;

        LOG_DEBUG << m_ConfigUrl;

        QUrl url;
        url.setUrl(m_ConfigUrl);

        QNetworkRequest request(url);
        QNetworkReply *reply = m_NetworkManager->get(request);
        Q_UNUSED(reply);
    }

    void RemoteConfig::replyReceived(QNetworkReply *networkReply) {
        LOG_DEBUG << "#";

        if (networkReply->error() == QNetworkReply::NoError) {
            QJsonParseError error;

            auto replyData = networkReply->readAll();
            LOG_INTEGRATION_TESTS << replyData;

            m_Config = QJsonDocument::fromJson(replyData, &error);

            if (error.error == QJsonParseError::NoError) {
                emit configArrived();
            } else {
                LOG_WARNING << "Failed to parse remote json" << error.errorString();
            }
        } else {
            LOG_WARNING << "Config download failed:" << networkReply->errorString();
        }

        networkReply->deleteLater();
    }
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_FUN_MATRIX_EXP_2X2_HPP
#define STAN_MATH_PRIM_FUN_MATRIX_EXP_2X2_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/fun/cosh.hpp>
#include <stan/math/prim/fun/exp.hpp>
#include <stan/math/prim/fun/sinh.hpp>
#include <stan/math/prim/fun/sqrt.hpp>
#include <stan/math/prim/fun/square.hpp>
#include <cmath>

namespace stan {
namespace math {

/**
 * Return the matrix exponential of a 2x2 matrix. Reference for
 * algorithm: http://mathworld.wolfram.com/MatrixExponential.html
 * Note: algorithm only works if delta > 0;
 *
 * @tparam EigMat type of the matrix
 * @param[in] A 2x2 matrix to exponentiate.
 * @return Matrix exponential of A.
 */
template <typename EigMat, require_eigen_t<EigMat>* = nullptr>
Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic>
matrix_exp_2x2(const EigMat& A) {
  using std::cosh;
  using std::exp;
  using std::sinh;
  using std::sqrt;

  using T = value_type_t<EigMat>;
  T a = A(0, 0), b = A(0, 1), c = A(1, 0), d = A(1, 1), delta;
  delta = sqrt(square(a - d) + 4 * b * c);

  Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> B(2, 2);
  T half_delta = 0.5 * delta;
  T cosh_half_delta = cosh(half_delta);
  T sinh_half_delta = sinh(half_delta);
  T exp_half_a_plus_d = exp(0.5 * (a + d));
  T Two_exp_sinh = 2 * exp_half_a_plus_d * sinh_half_delta;
  T delta_cosh = delta * cosh_half_delta;
  T ad_sinh_half_delta = (a - d) * sinh_half_delta;

  B(0, 0) = exp_half_a_plus_d * (delta_cosh + ad_sinh_half_delta);
  B(0, 1) = b * Two_exp_sinh;
  B(1, 0) = c * Two_exp_sinh;
  B(1, 1) = exp_half_a_plus_d * (delta_cosh - ad_sinh_half_delta);

  // use pade approximation if cosh & sinh ops overflow to NaN
  if ((B.array() != B.array()).any()) {
    return matrix_exp_pade(A);
  } else {
    return B / delta;
  }
}

}  // namespace math
}  // namespace stan

#endif
<commit_msg>replace naive C style NaN check with Eigen's hasNaN<commit_after>#ifndef STAN_MATH_PRIM_FUN_MATRIX_EXP_2X2_HPP
#define STAN_MATH_PRIM_FUN_MATRIX_EXP_2X2_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/fun/cosh.hpp>
#include <stan/math/prim/fun/exp.hpp>
#include <stan/math/prim/fun/sinh.hpp>
#include <stan/math/prim/fun/sqrt.hpp>
#include <stan/math/prim/fun/square.hpp>
#include <cmath>

namespace stan {
namespace math {

/**
 * Return the matrix exponential of a 2x2 matrix. Reference for
 * algorithm: http://mathworld.wolfram.com/MatrixExponential.html
 * Note: algorithm only works if delta > 0;
 *
 * @tparam EigMat type of the matrix
 * @param[in] A 2x2 matrix to exponentiate.
 * @return Matrix exponential of A.
 */
template <typename EigMat, require_eigen_t<EigMat>* = nullptr>
Eigen::Matrix<value_type_t<EigMat>, Eigen::Dynamic, Eigen::Dynamic>
matrix_exp_2x2(const EigMat& A) {
  using std::cosh;
  using std::exp;
  using std::sinh;
  using std::sqrt;

  using T = value_type_t<EigMat>;
  T a = A(0, 0), b = A(0, 1), c = A(1, 0), d = A(1, 1), delta;
  delta = sqrt(square(a - d) + 4 * b * c);

  Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> B(2, 2);
  T half_delta = 0.5 * delta;
  T cosh_half_delta = cosh(half_delta);
  T sinh_half_delta = sinh(half_delta);
  T exp_half_a_plus_d = exp(0.5 * (a + d));
  T Two_exp_sinh = 2 * exp_half_a_plus_d * sinh_half_delta;
  T delta_cosh = delta * cosh_half_delta;
  T ad_sinh_half_delta = (a - d) * sinh_half_delta;

  B(0, 0) = exp_half_a_plus_d * (delta_cosh + ad_sinh_half_delta);
  B(0, 1) = b * Two_exp_sinh;
  B(1, 0) = c * Two_exp_sinh;
  B(1, 1) = exp_half_a_plus_d * (delta_cosh - ad_sinh_half_delta);

  // use pade approximation if cosh & sinh ops overflow to NaN
  if (B.hasNaN()) {
    return matrix_exp_pade(A);
  } else {
    return B / delta;
  }
}

}  // namespace math
}  // namespace stan

#endif
<|endoftext|>