<commit_before>#include "antsUtilities.h"
#include <algorithm>

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

#include "itkDeformationFieldGradientTensorImageFilter.h"
#include "itkDeterminantTensorImageFilter.h"
#include "itkGeometricJacobianDeterminantImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMaximumImageFilter.h"

namespace ants
{
template <unsigned int ImageDimension>
int CreateJacobianDeterminantImage( int argc, char *argv[] )
{
  typedef double RealType;
  typedef itk::Image<RealType, ImageDimension> ImageType;
  typedef itk::Vector<RealType, ImageDimension> VectorType;
  typedef itk::Image<VectorType, ImageDimension> VectorImageType;

  /**
   * Read in vector field
   */
  typedef itk::ImageFileReader<VectorImageType> ReaderType;
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[2] );
  reader->Update();

  typename ImageType::Pointer jacobian = ITK_NULLPTR;

  typename ImageType::Pointer minimumConstantImage = ImageType::New();
  minimumConstantImage->CopyInformation( reader->GetOutput() );
  minimumConstantImage->SetRegions( reader->GetOutput()->GetRequestedRegion() );
  minimumConstantImage->Allocate();
  minimumConstantImage->FillBuffer( 0.001 );

  bool calculateLogJacobian = false;
  if ( argc > 4 )
    {
    calculateLogJacobian = static_cast<bool>( atoi( argv[4] ) );
    }

  bool calculateGeometricJacobian = false;
  if ( argc > 5 )
    {
    calculateGeometricJacobian = static_cast<bool>( atoi( argv[5] ) );
    }

  if( calculateGeometricJacobian )
    {
    typedef itk::GeometricJacobianDeterminantImageFilter
      <VectorImageType, RealType, ImageType> JacobianFilterType;
    typename JacobianFilterType::Pointer jacobianFilter = JacobianFilterType::New();
    jacobianFilter->SetInput( reader->GetOutput() );

    jacobian = jacobianFilter->GetOutput();
    jacobian->Update();
    jacobian->DisconnectPipeline();
    }
  else
    {
    typedef itk::DeformationFieldGradientTensorImageFilter<VectorImageType, RealType> JacobianFilterType;
    typename JacobianFilterType::Pointer jacobianFilter = JacobianFilterType::New();
    jacobianFilter->SetInput( reader->GetOutput() );
    jacobianFilter->SetCalculateJacobian( true );
    jacobianFilter->SetUseImageSpacing( true );
    jacobianFilter->SetOrder( 2 );
    jacobianFilter->SetUseCenteredDifference( true );

    typedef itk::DeterminantTensorImageFilter<typename JacobianFilterType::OutputImageType, RealType>
      DeterminantFilterType;
    typename DeterminantFilterType::Pointer determinantFilter = DeterminantFilterType::New();
    determinantFilter->SetInput( jacobianFilter->GetOutput() );
    determinantFilter->Update();

    minimumConstantImage->FillBuffer( 0.0 );

    typedef itk::MaximumImageFilter<ImageType, ImageType, ImageType> MaxFilterType;
    typename MaxFilterType::Pointer maxFilter = MaxFilterType::New();
    maxFilter->SetInput1( determinantFilter->GetOutput() );
    maxFilter->SetInput2( minimumConstantImage );

    jacobian = maxFilter->GetOutput();
    jacobian->Update();
    jacobian->DisconnectPipeline();
    }

  if( calculateLogJacobian )
    {
    minimumConstantImage->FillBuffer( 0.001 );

    typedef itk::MaximumImageFilter<ImageType, ImageType, ImageType> MaxFilterType;
    typename MaxFilterType::Pointer maxFilter = MaxFilterType::New();
    maxFilter->SetInput1( jacobian );
    maxFilter->SetInput2( minimumConstantImage );

    typedef itk::LogImageFilter<ImageType, ImageType> LogFilterType;
    typename LogFilterType::Pointer logFilter = LogFilterType::New();
    logFilter->SetInput( maxFilter->GetOutput() );
    logFilter->Update();

    typedef itk::ImageFileWriter<ImageType> ImageWriterType;
    typename ImageWriterType::Pointer writer = ImageWriterType::New();
    writer->SetFileName( argv[3] );
    writer->SetInput( logFilter->GetOutput() );
    writer->Update();
    }
  else
    {
    typedef itk::ImageFileWriter<ImageType> ImageWriterType;
    typename ImageWriterType::Pointer writer = ImageWriterType::New();
    writer->SetFileName( argv[3] );
    writer->SetInput( jacobian );
    writer->Update();
    }

  return EXIT_SUCCESS;
}

// entry point for the library; parameter 'args' is equivalent to 'argv' in (argc,argv) of commandline parameters to
// 'main()'
int CreateJacobianDeterminantImage( std::vector<std::string> args, std::ostream* itkNotUsed( out_stream ) )
{
  // put the arguments coming in as 'args' into standard (argc,argv) format;
  // 'args' doesn't have the command name as first, argument, so add it manually;
  // 'args' may have adjacent arguments concatenated into one argument,
  // which the parser should handle
  args.insert( args.begin(), "CreateJacobianDeterminantImage" );

  int     argc = args.size();
  char* * argv = new char *[args.size() + 1];
  for( unsigned int i = 0; i < args.size(); ++i )
    {
    // allocate space for the string plus a null character
    argv[i] = new char[args[i].length() + 1];
    std::strncpy( argv[i], args[i].c_str(), args[i].length() );
    // place the null character in the end
    argv[i][args[i].length()] = '\0';
    }
  argv[argc] = ITK_NULLPTR;
  // class to automatically cleanup argv upon destruction
  class Cleanup_argv
  {
public:
    Cleanup_argv( char* * argv_, int argc_plus_one_ ) : argv( argv_ ), argc_plus_one( argc_plus_one_ )
    {
    }

    ~Cleanup_argv()
    {
      for( unsigned int i = 0; i < argc_plus_one; ++i )
        {
        delete[] argv[i];
        }
      delete[] argv;
    }

private:
    char* *      argv;
    unsigned int argc_plus_one;
  };
  Cleanup_argv cleanup_argv( argv, argc + 1 );

  // antscout->set_stream( out_stream );

  if( argc < 3 )
    {
    std::cout << "Usage: " << argv[0] << " imageDimension deformationField outputImage [doLogJacobian=0] [useGeometric=0]" << std::endl;
    return EXIT_FAILURE;
    }

  switch( atoi( argv[1] ) )
    {
    case 2:
      {
      CreateJacobianDeterminantImage<2>( argc, argv );
      }
      break;
    case 3:
      {
      CreateJacobianDeterminantImage<3>( argc, argv );
      }
      break;
    default:
      std::cout << "Unsupported dimension" << std::endl;
      return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}
} // namespace ants
<commit_msg>BUG: (antsr-specific) need ReadWriteData<commit_after>#include "antsUtilities.h"
#include <algorithm>
#include "ReadWriteData.h"
#include "itkDeformationFieldGradientTensorImageFilter.h"
#include "itkDeterminantTensorImageFilter.h"
#include "itkGeometricJacobianDeterminantImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMaximumImageFilter.h"

namespace ants
{
template <unsigned int ImageDimension>
int CreateJacobianDeterminantImage( int argc, char *argv[] )
{
  typedef double RealType;
  typedef itk::Image<RealType, ImageDimension> ImageType;
  typedef itk::Vector<RealType, ImageDimension> VectorType;
  typedef itk::Image<VectorType, ImageDimension> VectorImageType;

  /**
   * Read in vector field
   */
  typedef itk::ImageFileReader<VectorImageType> ReaderType;
  typename ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[2] );
  reader->Update();

  typename ImageType::Pointer jacobian = ITK_NULLPTR;

  typename ImageType::Pointer minimumConstantImage = ImageType::New();
  minimumConstantImage->CopyInformation( reader->GetOutput() );
  minimumConstantImage->SetRegions( reader->GetOutput()->GetRequestedRegion() );
  minimumConstantImage->Allocate();
  minimumConstantImage->FillBuffer( 0.001 );

  bool calculateLogJacobian = false;
  if ( argc > 4 )
    {
    calculateLogJacobian = static_cast<bool>( atoi( argv[4] ) );
    }

  bool calculateGeometricJacobian = false;
  if ( argc > 5 )
    {
    calculateGeometricJacobian = static_cast<bool>( atoi( argv[5] ) );
    }

  if( calculateGeometricJacobian )
    {
    typedef itk::GeometricJacobianDeterminantImageFilter
      <VectorImageType, RealType, ImageType> JacobianFilterType;
    typename JacobianFilterType::Pointer jacobianFilter = JacobianFilterType::New();
    jacobianFilter->SetInput( reader->GetOutput() );

    jacobian = jacobianFilter->GetOutput();
    jacobian->Update();
    jacobian->DisconnectPipeline();
    }
  else
    {
    typedef itk::DeformationFieldGradientTensorImageFilter<VectorImageType, RealType> JacobianFilterType;
    typename JacobianFilterType::Pointer jacobianFilter = JacobianFilterType::New();
    jacobianFilter->SetInput( reader->GetOutput() );
    jacobianFilter->SetCalculateJacobian( true );
    jacobianFilter->SetUseImageSpacing( true );
    jacobianFilter->SetOrder( 2 );
    jacobianFilter->SetUseCenteredDifference( true );

    typedef itk::DeterminantTensorImageFilter<typename JacobianFilterType::OutputImageType, RealType>
      DeterminantFilterType;
    typename DeterminantFilterType::Pointer determinantFilter = DeterminantFilterType::New();
    determinantFilter->SetInput( jacobianFilter->GetOutput() );
    determinantFilter->Update();

    minimumConstantImage->FillBuffer( 0.0 );

    typedef itk::MaximumImageFilter<ImageType, ImageType, ImageType> MaxFilterType;
    typename MaxFilterType::Pointer maxFilter = MaxFilterType::New();
    maxFilter->SetInput1( determinantFilter->GetOutput() );
    maxFilter->SetInput2( minimumConstantImage );

    jacobian = maxFilter->GetOutput();
    jacobian->Update();
    jacobian->DisconnectPipeline();
    }

  if( calculateLogJacobian )
    {
    minimumConstantImage->FillBuffer( 0.001 );

    typedef itk::MaximumImageFilter<ImageType, ImageType, ImageType> MaxFilterType;
    typename MaxFilterType::Pointer maxFilter = MaxFilterType::New();
    maxFilter->SetInput1( jacobian );
    maxFilter->SetInput2( minimumConstantImage );

    typedef itk::LogImageFilter<ImageType, ImageType> LogFilterType;
    typename LogFilterType::Pointer logFilter = LogFilterType::New();
    logFilter->SetInput( maxFilter->GetOutput() );
    logFilter->Update();
    WriteImage<ImageType>(logFilter->GetOutput(), argv[3] );
    }
  else
    {
    WriteImage<ImageType>(jacobian, argv[3] );
    }
  return EXIT_SUCCESS;
}

// entry point for the library; parameter 'args' is equivalent to 'argv' in (argc,argv) of commandline parameters to
// 'main()'
int CreateJacobianDeterminantImage( std::vector<std::string> args, std::ostream* itkNotUsed( out_stream ) )
{
  // put the arguments coming in as 'args' into standard (argc,argv) format;
  // 'args' doesn't have the command name as first, argument, so add it manually;
  // 'args' may have adjacent arguments concatenated into one argument,
  // which the parser should handle
  args.insert( args.begin(), "CreateJacobianDeterminantImage" );

  int     argc = args.size();
  char* * argv = new char *[args.size() + 1];
  for( unsigned int i = 0; i < args.size(); ++i )
    {
    // allocate space for the string plus a null character
    argv[i] = new char[args[i].length() + 1];
    std::strncpy( argv[i], args[i].c_str(), args[i].length() );
    // place the null character in the end
    argv[i][args[i].length()] = '\0';
    }
  argv[argc] = ITK_NULLPTR;
  // class to automatically cleanup argv upon destruction
  class Cleanup_argv
  {
public:
    Cleanup_argv( char* * argv_, int argc_plus_one_ ) : argv( argv_ ), argc_plus_one( argc_plus_one_ )
    {
    }

    ~Cleanup_argv()
    {
      for( unsigned int i = 0; i < argc_plus_one; ++i )
        {
        delete[] argv[i];
        }
      delete[] argv;
    }

private:
    char* *      argv;
    unsigned int argc_plus_one;
  };
  Cleanup_argv cleanup_argv( argv, argc + 1 );

  // antscout->set_stream( out_stream );

  if( argc < 3 )
    {
    std::cout << "Usage: " << argv[0] << " imageDimension deformationField outputImage [doLogJacobian=0] [useGeometric=0]" << std::endl;
    return EXIT_FAILURE;
    }

  switch( atoi( argv[1] ) )
    {
    case 2:
      {
      CreateJacobianDeterminantImage<2>( argc, argv );
      }
      break;
    case 3:
      {
      CreateJacobianDeterminantImage<3>( argc, argv );
      }
      break;
    default:
      std::cout << "Unsupported dimension" << std::endl;
      return EXIT_FAILURE;
    }
  return EXIT_SUCCESS;
}
} // namespace ants
<|endoftext|>


<commit_before>#include <tuple>
#include <utility>

namespace
{

//holds a sequence of integers.
template<int ...>
struct sequence { };

//generate a sequence of incrementing values starting at zero
template<int N, int ...S>
struct generate_sequence
{
  typedef typename generate_sequence<N-1, N-1, S...>::type type;
};

//generate a sequence of incrementing values starting at zero
template<int ...S>
struct generate_sequence<0, S...>
{
  typedef sequence<S...> type;
};

//apply a functor to each element in a parameter pack
template<class First, class ...T>
struct forEach
{
  template<typename Functor>
  void operator()(Functor f, First first, T... t) const
  {
    forEach<T...>()(f,t...);
  }
};

//apply a functor to each element in a parameter pack
template<class First>
struct forEach<First>
{
  template<typename Functor>
  void operator()(Functor f, First first) const
  {
  }
};

//applies the functor to each element in a parameter pack
template<class  Functor, class ...T>
void for_each(Functor f, T... items)
{
  ::forEach<T...>()(f,items...);
}

//special version of for_each that is a helper to get the length of indicies
//as a parameter type. I can't figure out how to do this step inside for_each specialized
//on tuple
template<class Functor, class ...T, int ...Indices>
void for_each(Functor f, std::tuple<T...> tuple, ::sequence<Indices...>)
{
  ::for_each(f,std::get<Indices>(tuple)...);
}

//function overload that detects tuples being sent to for each
//and expands the tuple elements
template<class Functor, class ...T>
void for_each(Functor f, std::tuple<T...>& tuple)
{
  //to iterate each item in the tuple we have to convert back from
  //a tuple to a parameter pack
  enum { len = std::tuple_size< std::tuple<T...> >::value};
  typedef typename ::generate_sequence<len>::type SequenceType;
  ::for_each(f,tuple,SequenceType());
}

template<typename ...Values>
void InvokeTuple(Values... v)
{
  std::tuple<Values...> tuple(v...);
  ::for_each(tuple);
}

}

int main(int argc, char** argv)
{
  InvokeTuple("0",'1',2.0f,3);
  return 0;
}
<commit_msg>Update the C11 try compile code to actually compile.<commit_after>#include <tuple>
#include <utility>

namespace
{

struct test_functor {
  template<class T>
  void operator()(T& t) const { t = T(); }
};

//holds a sequence of integers.
template<int ...>
struct sequence { };

//generate a sequence of incrementing values starting at zero
template<int N, int ...S>
struct generate_sequence
{
  typedef typename generate_sequence<N-1, N-1, S...>::type type;
};

//generate a sequence of incrementing values starting at zero
template<int ...S>
struct generate_sequence<0, S...>
{
  typedef sequence<S...> type;
};

//apply a functor to each element in a parameter pack
template<class First, class ...T>
struct forEach
{
  template<typename Functor>
  void operator()(Functor f, First first, T... t) const
  {
    forEach<T...>()(f,t...);
  }
};

//apply a functor to each element in a parameter pack
template<class First>
struct forEach<First>
{
  template<typename Functor>
  void operator()(Functor f, First first) const
  {
  }
};

//applies the functor to each element in a parameter pack
template<class  Functor, class ...T>
void for_each(Functor f, T... items)
{
  ::forEach<T...>()(f,items...);
}

//special version of for_each that is a helper to get the length of indicies
//as a parameter type. I can't figure out how to do this step inside for_each specialized
//on tuple
template<class Functor, class ...T, int ...Indices>
void for_each(Functor f, std::tuple<T...> tuple, ::sequence<Indices...>)
{
  ::for_each(f,std::get<Indices>(tuple)...);
}

//function overload that detects tuples being sent to for each
//and expands the tuple elements
template<class Functor, class ...T>
void for_each(Functor f, std::tuple<T...>& tuple)
{
  //to iterate each item in the tuple we have to convert back from
  //a tuple to a parameter pack
  enum { len = std::tuple_size< std::tuple<T...> >::value};
  typedef typename ::generate_sequence<len>::type SequenceType;
  ::for_each(f,tuple,SequenceType());
}

template<typename ...Values>
void InvokeTuple(Values... v)
{
  std::tuple<Values...> tuple(v...);
  ::for_each(::test_functor(),tuple);
}

}

int main(int argc, char** argv)
{
  InvokeTuple("0",'1',2.0f,3);
  return 0;
}
<|endoftext|>


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

  Library:   CTK

  Copyright (c) 2010  Kitware 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.commontk.org/LICENSE

  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.

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

// Qt includes
#include <QWidget>
#include <QList>
#include <QPushButton>
#include <QBoxLayout>
#include <QDebug>
#include <QPointer>
#include <QStyle>

// CTK includes
#include "ctkWorkflowButtonBoxWidget.h"
#include "ctkWorkflowStep.h"
#include "ctkWorkflowWidgetStep.h"
#include "ctkWorkflow.h"

// STD includes
#include <iostream>

//-----------------------------------------------------------------------------
class ctkWorkflowButtonBoxWidgetPrivate : public ctkPrivate<ctkWorkflowButtonBoxWidget>
{
public:
  CTK_DECLARE_PUBLIC(ctkWorkflowButtonBoxWidget);
  ctkWorkflowButtonBoxWidgetPrivate();
  ~ctkWorkflowButtonBoxWidgetPrivate(){}

  void setupUi(QWidget * newParent);

  QPointer<ctkWorkflow>    Workflow;

  // Convenient typedefs
  typedef QMap<QPushButton*, ctkWorkflowStep*> ButtonToStepMapType;

  // The buttons on the widget (maintain maps associating each forward/goTo button with its step)
  QPushButton*        BackButton;
  QString             BackButtonDefaultText;
  QPushButton*        NextButton;
  QString             NextButtonDefaultText;
  ButtonToStepMapType GoToButtonToStepMap;

  // Direction for layout (for use with QBoxLayout only)
  QBoxLayout::Direction Direction;

  bool HideInvalidButtons;

  // Functions to add/remove buttons
  void updateBackButton(ctkWorkflowStep* currentStep);
  void updateNextButton(ctkWorkflowStep* currentStep);
  void updateGoToButtons(ctkWorkflowStep* currentStep);

};

//-----------------------------------------------------------------------------
// ctkWorkflowButtonBoxWidgetPrivate methods

//-----------------------------------------------------------------------------
ctkWorkflowButtonBoxWidgetPrivate::ctkWorkflowButtonBoxWidgetPrivate()
{
  this->BackButton = 0;
  this->BackButtonDefaultText = "Back";
  this->NextButton = 0;
  this->NextButtonDefaultText = "Next";
  this->Direction = QBoxLayout::LeftToRight;
  this->HideInvalidButtons = false;
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidgetPrivate::setupUi(QWidget * newParent)
{
  QBoxLayout * boxLayout = new QBoxLayout(this->Direction, newParent);
  boxLayout->setSpacing(0);
  boxLayout->setContentsMargins(0, 0, 0, 0);
  newParent->setLayout(boxLayout);

  // Retrieve standard icons
  QIcon backIcon = newParent->style()->standardIcon(QStyle::SP_ArrowLeft);
  QIcon nextIcon = newParent->style()->standardIcon(QStyle::SP_ArrowRight);

  // Setup the buttons
  this->BackButton = new QPushButton(backIcon, this->BackButtonDefaultText, newParent);
  newParent->layout()->addWidget(this->BackButton);

  this->NextButton = new QPushButton(nextIcon, this->NextButtonDefaultText, newParent);
  this->NextButton->setLayoutDirection(Qt::RightToLeft);
  newParent->layout()->addWidget(this->NextButton);
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidgetPrivate::updateBackButton(ctkWorkflowStep* currentStep)
{
  CTK_P(ctkWorkflowButtonBoxWidget);

  Q_ASSERT(this->Workflow);
  Q_ASSERT(currentStep);
  Q_ASSERT(p->layout());

  ctkWorkflowWidgetStep* step = qobject_cast<ctkWorkflowWidgetStep*>(currentStep);

  // Set the back button text
  QString backButtonText = this->BackButtonDefaultText;
  if (step && !step->backButtonText().isEmpty())
    {
    backButtonText = step->backButtonText();
    }
  this->BackButton->setText(backButtonText);

  // Enable and show the back button if we can go backward
  if (this->Workflow->canGoBackward(currentStep))
    {
    this->BackButton->setEnabled(true);
    this->BackButton->show();

    // Apply the buttonBox hints if possible
    if (step)
      {
      this->BackButton->setDisabled(
          step->buttonBoxHints() & ctkWorkflowWidgetStep::BackButtonDisabled);
      this->BackButton->setHidden(
          step->buttonBoxHints() & ctkWorkflowWidgetStep::BackButtonHidden);
      }
    }
  // Disable the back button if we can't go backward, and optionally hide it
  else
    {
    this->BackButton->setEnabled(false);
    this->HideInvalidButtons ? this->BackButton->hide() : this->BackButton->show();
    }
}

//-----------------------------------------------------------------------------
// This will change for branching workflows, to look more like updateGoToButtons()
void ctkWorkflowButtonBoxWidgetPrivate::updateNextButton(ctkWorkflowStep* currentStep)
{
  CTK_P(ctkWorkflowButtonBoxWidget);

  Q_ASSERT(this->Workflow);
  Q_ASSERT(currentStep);
  Q_ASSERT(p->layout());

  ctkWorkflowWidgetStep* step = qobject_cast<ctkWorkflowWidgetStep*>(currentStep);

  // Set the next button text
  QString nextButtonText = this->NextButtonDefaultText;
  if (step && !step->nextButtonText().isEmpty())
    {
    nextButtonText = step->nextButtonText();
    }
  this->NextButton->setText(nextButtonText);

  // Enable and show the next button if we can go forward
  if (this->Workflow->canGoForward(currentStep))
    {
    this->NextButton->setEnabled(true);
    this->NextButton->show();

    // Apply the buttonBox hints if possible
    if (step)
      {
      this->NextButton->setDisabled(
          step->buttonBoxHints() & ctkWorkflowWidgetStep::NextButtonDisabled);
      this->NextButton->setHidden(
          step->buttonBoxHints() & ctkWorkflowWidgetStep::NextButtonHidden);
      }
    }
  // Disable the next button if we can't go forward, and optionally hide it
  else
    {
    this->NextButton->setEnabled(false);
    this->HideInvalidButtons ? this->NextButton->hide() : this->NextButton->show();
    }
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidgetPrivate::updateGoToButtons(ctkWorkflowStep* currentStep)
{
  CTK_P(ctkWorkflowButtonBoxWidget);

  Q_ASSERT(this->Workflow);
  Q_ASSERT(currentStep);
  Q_ASSERT(p->layout());

  // Change the buttons only if the set of steps to have goTo buttons is either empty or has changed
  QSet<ctkWorkflowStep*> goToStepsToHaveButtons = QSet<ctkWorkflowStep*>::fromList(this->Workflow->finishSteps());
  QSet<ctkWorkflowStep*> goToStepsThatHaveButtons = QSet<ctkWorkflowStep*>::fromList(this->GoToButtonToStepMap.values());

  // Remove the buttons if the set of steps to have goTo buttons has changed
  if (!this->GoToButtonToStepMap.isEmpty() && goToStepsThatHaveButtons != goToStepsToHaveButtons)
    {
    foreach (QPushButton* goToButton, this->GoToButtonToStepMap.keys())
      {
      p->layout()->removeWidget(goToButton);
      delete goToButton;
      }
    this->GoToButtonToStepMap.clear();
    }

  // Create the buttons, either for the first time or after removing them above
  if (this->GoToButtonToStepMap.isEmpty())
    {
    // Create a button for each of the goToSteps
    foreach (ctkWorkflowStep* step, goToStepsToHaveButtons)
      {
      // TODO shouldn't have id here
      QPushButton* goToButton = new QPushButton(step->id());
      p->layout()->addWidget(goToButton);
      QObject::connect(goToButton, SIGNAL(clicked()), p, SLOT(prepareGoToStep()));
      this->GoToButtonToStepMap[goToButton] = step;
      }

    }

  // Show/hide the goTo buttons depending on whether they are accessible from the current step
  foreach (QPushButton* goToButton, this->GoToButtonToStepMap.keys())
    {
    // TODO enable and show the goTo button if we can go to it
    // ctkWorkflowStep* goToStep = this->GoToButtonToStepMap[goToButton];
    // if (this->Workflow->canGoToStep(currentStep, goToStep))
    // for now we'll assume we can go to the step
    if (true)
      {
      goToButton->setEnabled(true);
      goToButton->show();
      }
    // disable the goTo button if we can't go to it, and optionally hide it
    else
      {
      goToButton->setEnabled(false);
      this->HideInvalidButtons ? goToButton->hide() : goToButton->show();
      }
    }
}

//-----------------------------------------------------------------------------
// ctkWorkflowButtonBoxWidget methods

//-----------------------------------------------------------------------------
ctkWorkflowButtonBoxWidget::ctkWorkflowButtonBoxWidget(ctkWorkflow* newWorkflow, QWidget* newParent) :
    Superclass(newParent)
{
  CTK_INIT_PRIVATE(ctkWorkflowButtonBoxWidget);
  CTK_D(ctkWorkflowButtonBoxWidget);

  d->setupUi(this);

  this->setWorkflow(newWorkflow);
}

//-----------------------------------------------------------------------------
ctkWorkflowButtonBoxWidget::ctkWorkflowButtonBoxWidget(QWidget* newParent) :
    Superclass(newParent)
{
  CTK_INIT_PRIVATE(ctkWorkflowButtonBoxWidget);
  CTK_D(ctkWorkflowButtonBoxWidget);

  d->setupUi(this);
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::setWorkflow(ctkWorkflow * newWorkflow)
{
  CTK_D(ctkWorkflowButtonBoxWidget);

  if (d->Workflow == newWorkflow)
    {
    return;
    }

  // Disconnect
  if (!d->Workflow.isNull())
    {
    QObject::disconnect(d->BackButton, SIGNAL(clicked()), d->Workflow, SLOT(goBackward()));
    QObject::disconnect(d->NextButton, SIGNAL(clicked()), d->Workflow, SLOT(goForward()));
    }

  // Connect
  if (newWorkflow)
    {
    QObject::connect(d->BackButton, SIGNAL(clicked()), newWorkflow, SLOT(goBackward()));
    QObject::connect(d->NextButton, SIGNAL(clicked()), newWorkflow, SLOT(goForward()));
    }

  d->Workflow = newWorkflow;
}

//-----------------------------------------------------------------------------
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, QString, backButtonDefaultText,
            BackButtonDefaultText);

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::setBackButtonDefaultText(const QString& defaultText)
{
  CTK_D(ctkWorkflowButtonBoxWidget);
  d->BackButtonDefaultText = defaultText;
  if (d->Workflow)
    {
    this->updateButtons();
    }
  else
    {
    d->BackButton->setText(d->BackButtonDefaultText);
    }
}

//-----------------------------------------------------------------------------
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, QString, nextButtonDefaultText,
            NextButtonDefaultText);

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::setNextButtonDefaultText(const QString& defaultText)
{
  CTK_D(ctkWorkflowButtonBoxWidget);
  d->NextButtonDefaultText = defaultText;
  this->updateButtons();
  if (d->Workflow)
    {
    this->updateButtons();
    }
  else
    {
    d->NextButton->setText(d->NextButtonDefaultText);
    }
}

//-----------------------------------------------------------------------------
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, ctkWorkflow*, workflow, Workflow);
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, QPushButton*, backButton, BackButton);
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, QBoxLayout::Direction, direction, Direction);
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, bool, hideInvalidButtons, HideInvalidButtons);
CTK_SET_CXX(ctkWorkflowButtonBoxWidget, bool, setHideInvalidButtons, HideInvalidButtons);

//-----------------------------------------------------------------------------
// TODO will be list of next buttons for branching workflow
QPushButton* ctkWorkflowButtonBoxWidget::nextButton()const
{
  CTK_D(const ctkWorkflowButtonBoxWidget);
  return d->NextButton;
}

//-----------------------------------------------------------------------------
QList<QPushButton*> ctkWorkflowButtonBoxWidget::goToButtons()const
{
  CTK_D(const ctkWorkflowButtonBoxWidget);
  return d->GoToButtonToStepMap.keys();
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::setDirection(const QBoxLayout::Direction& newDirection)
{
  if (QBoxLayout* layout = qobject_cast<QBoxLayout*>(this->layout()))
    {
    layout->setDirection(newDirection);
    }
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::updateButtons()
{

  CTK_D(ctkWorkflowButtonBoxWidget);
  if (d->Workflow.isNull())
    {
    return;
    }

  ctkWorkflowStep* currentStep = d->Workflow->currentStep();
  if (!currentStep)
    {
    return;
    }

  d->updateBackButton(currentStep);
  d->updateNextButton(currentStep);
  d->updateGoToButtons(currentStep);
}

//--------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::prepareGoToStep()
{
  CTK_D(ctkWorkflowButtonBoxWidget);
  if (QPushButton* button = qobject_cast<QPushButton*>(QObject::sender()))
    {
    if (ctkWorkflowStep* step = d->GoToButtonToStepMap.value(button))
      {
      d->Workflow->goToStep(step->id());
      }
    }
}
<commit_msg>STYLE: WorkflowWidget - Remove extra call to updateButtons in ctkWorkflowButtonBoxWidget<commit_after>/*=========================================================================

  Library:   CTK

  Copyright (c) 2010  Kitware 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.commontk.org/LICENSE

  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.

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

// Qt includes
#include <QWidget>
#include <QList>
#include <QPushButton>
#include <QBoxLayout>
#include <QDebug>
#include <QPointer>
#include <QStyle>

// CTK includes
#include "ctkWorkflowButtonBoxWidget.h"
#include "ctkWorkflowStep.h"
#include "ctkWorkflowWidgetStep.h"
#include "ctkWorkflow.h"

// STD includes
#include <iostream>

//-----------------------------------------------------------------------------
class ctkWorkflowButtonBoxWidgetPrivate : public ctkPrivate<ctkWorkflowButtonBoxWidget>
{
public:
  CTK_DECLARE_PUBLIC(ctkWorkflowButtonBoxWidget);
  ctkWorkflowButtonBoxWidgetPrivate();
  ~ctkWorkflowButtonBoxWidgetPrivate(){}

  void setupUi(QWidget * newParent);

  QPointer<ctkWorkflow>    Workflow;

  // Convenient typedefs
  typedef QMap<QPushButton*, ctkWorkflowStep*> ButtonToStepMapType;

  // The buttons on the widget (maintain maps associating each forward/goTo button with its step)
  QPushButton*        BackButton;
  QString             BackButtonDefaultText;
  QPushButton*        NextButton;
  QString             NextButtonDefaultText;
  ButtonToStepMapType GoToButtonToStepMap;

  // Direction for layout (for use with QBoxLayout only)
  QBoxLayout::Direction Direction;

  bool HideInvalidButtons;

  // Functions to add/remove buttons
  void updateBackButton(ctkWorkflowStep* currentStep);
  void updateNextButton(ctkWorkflowStep* currentStep);
  void updateGoToButtons(ctkWorkflowStep* currentStep);

};

//-----------------------------------------------------------------------------
// ctkWorkflowButtonBoxWidgetPrivate methods

//-----------------------------------------------------------------------------
ctkWorkflowButtonBoxWidgetPrivate::ctkWorkflowButtonBoxWidgetPrivate()
{
  this->BackButton = 0;
  this->BackButtonDefaultText = "Back";
  this->NextButton = 0;
  this->NextButtonDefaultText = "Next";
  this->Direction = QBoxLayout::LeftToRight;
  this->HideInvalidButtons = false;
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidgetPrivate::setupUi(QWidget * newParent)
{
  QBoxLayout * boxLayout = new QBoxLayout(this->Direction, newParent);
  boxLayout->setSpacing(0);
  boxLayout->setContentsMargins(0, 0, 0, 0);
  newParent->setLayout(boxLayout);

  // Retrieve standard icons
  QIcon backIcon = newParent->style()->standardIcon(QStyle::SP_ArrowLeft);
  QIcon nextIcon = newParent->style()->standardIcon(QStyle::SP_ArrowRight);

  // Setup the buttons
  this->BackButton = new QPushButton(backIcon, this->BackButtonDefaultText, newParent);
  newParent->layout()->addWidget(this->BackButton);

  this->NextButton = new QPushButton(nextIcon, this->NextButtonDefaultText, newParent);
  this->NextButton->setLayoutDirection(Qt::RightToLeft);
  newParent->layout()->addWidget(this->NextButton);
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidgetPrivate::updateBackButton(ctkWorkflowStep* currentStep)
{
  CTK_P(ctkWorkflowButtonBoxWidget);

  Q_ASSERT(this->Workflow);
  Q_ASSERT(currentStep);
  Q_ASSERT(p->layout());

  ctkWorkflowWidgetStep* step = qobject_cast<ctkWorkflowWidgetStep*>(currentStep);

  // Set the back button text
  QString backButtonText = this->BackButtonDefaultText;
  if (step && !step->backButtonText().isEmpty())
    {
    backButtonText = step->backButtonText();
    }
  this->BackButton->setText(backButtonText);

  // Enable and show the back button if we can go backward
  if (this->Workflow->canGoBackward(currentStep))
    {
    this->BackButton->setEnabled(true);
    this->BackButton->show();

    // Apply the buttonBox hints if possible
    if (step)
      {
      this->BackButton->setDisabled(
          step->buttonBoxHints() & ctkWorkflowWidgetStep::BackButtonDisabled);
      this->BackButton->setHidden(
          step->buttonBoxHints() & ctkWorkflowWidgetStep::BackButtonHidden);
      }
    }
  // Disable the back button if we can't go backward, and optionally hide it
  else
    {
    this->BackButton->setEnabled(false);
    this->HideInvalidButtons ? this->BackButton->hide() : this->BackButton->show();
    }
}

//-----------------------------------------------------------------------------
// This will change for branching workflows, to look more like updateGoToButtons()
void ctkWorkflowButtonBoxWidgetPrivate::updateNextButton(ctkWorkflowStep* currentStep)
{
  CTK_P(ctkWorkflowButtonBoxWidget);

  Q_ASSERT(this->Workflow);
  Q_ASSERT(currentStep);
  Q_ASSERT(p->layout());

  ctkWorkflowWidgetStep* step = qobject_cast<ctkWorkflowWidgetStep*>(currentStep);

  // Set the next button text
  QString nextButtonText = this->NextButtonDefaultText;
  if (step && !step->nextButtonText().isEmpty())
    {
    nextButtonText = step->nextButtonText();
    }
  this->NextButton->setText(nextButtonText);

  // Enable and show the next button if we can go forward
  if (this->Workflow->canGoForward(currentStep))
    {
    this->NextButton->setEnabled(true);
    this->NextButton->show();

    // Apply the buttonBox hints if possible
    if (step)
      {
      this->NextButton->setDisabled(
          step->buttonBoxHints() & ctkWorkflowWidgetStep::NextButtonDisabled);
      this->NextButton->setHidden(
          step->buttonBoxHints() & ctkWorkflowWidgetStep::NextButtonHidden);
      }
    }
  // Disable the next button if we can't go forward, and optionally hide it
  else
    {
    this->NextButton->setEnabled(false);
    this->HideInvalidButtons ? this->NextButton->hide() : this->NextButton->show();
    }
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidgetPrivate::updateGoToButtons(ctkWorkflowStep* currentStep)
{
  CTK_P(ctkWorkflowButtonBoxWidget);

  Q_ASSERT(this->Workflow);
  Q_ASSERT(currentStep);
  Q_ASSERT(p->layout());

  // Change the buttons only if the set of steps to have goTo buttons is either empty or has changed
  QSet<ctkWorkflowStep*> goToStepsToHaveButtons = QSet<ctkWorkflowStep*>::fromList(this->Workflow->finishSteps());
  QSet<ctkWorkflowStep*> goToStepsThatHaveButtons = QSet<ctkWorkflowStep*>::fromList(this->GoToButtonToStepMap.values());

  // Remove the buttons if the set of steps to have goTo buttons has changed
  if (!this->GoToButtonToStepMap.isEmpty() && goToStepsThatHaveButtons != goToStepsToHaveButtons)
    {
    foreach (QPushButton* goToButton, this->GoToButtonToStepMap.keys())
      {
      p->layout()->removeWidget(goToButton);
      delete goToButton;
      }
    this->GoToButtonToStepMap.clear();
    }

  // Create the buttons, either for the first time or after removing them above
  if (this->GoToButtonToStepMap.isEmpty())
    {
    // Create a button for each of the goToSteps
    foreach (ctkWorkflowStep* step, goToStepsToHaveButtons)
      {
      // TODO shouldn't have id here
      QPushButton* goToButton = new QPushButton(step->id());
      p->layout()->addWidget(goToButton);
      QObject::connect(goToButton, SIGNAL(clicked()), p, SLOT(prepareGoToStep()));
      this->GoToButtonToStepMap[goToButton] = step;
      }

    }

  // Show/hide the goTo buttons depending on whether they are accessible from the current step
  foreach (QPushButton* goToButton, this->GoToButtonToStepMap.keys())
    {
    // TODO enable and show the goTo button if we can go to it
    // ctkWorkflowStep* goToStep = this->GoToButtonToStepMap[goToButton];
    // if (this->Workflow->canGoToStep(currentStep, goToStep))
    // for now we'll assume we can go to the step
    if (true)
      {
      goToButton->setEnabled(true);
      goToButton->show();
      }
    // disable the goTo button if we can't go to it, and optionally hide it
    else
      {
      goToButton->setEnabled(false);
      this->HideInvalidButtons ? goToButton->hide() : goToButton->show();
      }
    }
}

//-----------------------------------------------------------------------------
// ctkWorkflowButtonBoxWidget methods

//-----------------------------------------------------------------------------
ctkWorkflowButtonBoxWidget::ctkWorkflowButtonBoxWidget(ctkWorkflow* newWorkflow, QWidget* newParent) :
    Superclass(newParent)
{
  CTK_INIT_PRIVATE(ctkWorkflowButtonBoxWidget);
  CTK_D(ctkWorkflowButtonBoxWidget);

  d->setupUi(this);

  this->setWorkflow(newWorkflow);
}

//-----------------------------------------------------------------------------
ctkWorkflowButtonBoxWidget::ctkWorkflowButtonBoxWidget(QWidget* newParent) :
    Superclass(newParent)
{
  CTK_INIT_PRIVATE(ctkWorkflowButtonBoxWidget);
  CTK_D(ctkWorkflowButtonBoxWidget);

  d->setupUi(this);
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::setWorkflow(ctkWorkflow * newWorkflow)
{
  CTK_D(ctkWorkflowButtonBoxWidget);

  if (d->Workflow == newWorkflow)
    {
    return;
    }

  // Disconnect
  if (!d->Workflow.isNull())
    {
    QObject::disconnect(d->BackButton, SIGNAL(clicked()), d->Workflow, SLOT(goBackward()));
    QObject::disconnect(d->NextButton, SIGNAL(clicked()), d->Workflow, SLOT(goForward()));
    }

  // Connect
  if (newWorkflow)
    {
    QObject::connect(d->BackButton, SIGNAL(clicked()), newWorkflow, SLOT(goBackward()));
    QObject::connect(d->NextButton, SIGNAL(clicked()), newWorkflow, SLOT(goForward()));
    }

  d->Workflow = newWorkflow;
}

//-----------------------------------------------------------------------------
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, QString, backButtonDefaultText,
            BackButtonDefaultText);

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::setBackButtonDefaultText(const QString& defaultText)
{
  CTK_D(ctkWorkflowButtonBoxWidget);
  d->BackButtonDefaultText = defaultText;
  if (d->Workflow)
    {
    this->updateButtons();
    }
  else
    {
    d->BackButton->setText(d->BackButtonDefaultText);
    }
}

//-----------------------------------------------------------------------------
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, QString, nextButtonDefaultText,
            NextButtonDefaultText);

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::setNextButtonDefaultText(const QString& defaultText)
{
  CTK_D(ctkWorkflowButtonBoxWidget);
  d->NextButtonDefaultText = defaultText;
  if (d->Workflow)
    {
    this->updateButtons();
    }
  else
    {
    d->NextButton->setText(d->NextButtonDefaultText);
    }
}

//-----------------------------------------------------------------------------
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, ctkWorkflow*, workflow, Workflow);
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, QPushButton*, backButton, BackButton);
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, QBoxLayout::Direction, direction, Direction);
CTK_GET_CXX(ctkWorkflowButtonBoxWidget, bool, hideInvalidButtons, HideInvalidButtons);
CTK_SET_CXX(ctkWorkflowButtonBoxWidget, bool, setHideInvalidButtons, HideInvalidButtons);

//-----------------------------------------------------------------------------
// TODO will be list of next buttons for branching workflow
QPushButton* ctkWorkflowButtonBoxWidget::nextButton()const
{
  CTK_D(const ctkWorkflowButtonBoxWidget);
  return d->NextButton;
}

//-----------------------------------------------------------------------------
QList<QPushButton*> ctkWorkflowButtonBoxWidget::goToButtons()const
{
  CTK_D(const ctkWorkflowButtonBoxWidget);
  return d->GoToButtonToStepMap.keys();
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::setDirection(const QBoxLayout::Direction& newDirection)
{
  if (QBoxLayout* layout = qobject_cast<QBoxLayout*>(this->layout()))
    {
    layout->setDirection(newDirection);
    }
}

//-----------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::updateButtons()
{

  CTK_D(ctkWorkflowButtonBoxWidget);
  if (d->Workflow.isNull())
    {
    return;
    }

  ctkWorkflowStep* currentStep = d->Workflow->currentStep();
  if (!currentStep)
    {
    return;
    }

  d->updateBackButton(currentStep);
  d->updateNextButton(currentStep);
  d->updateGoToButtons(currentStep);
}

//--------------------------------------------------------------------------
void ctkWorkflowButtonBoxWidget::prepareGoToStep()
{
  CTK_D(ctkWorkflowButtonBoxWidget);
  if (QPushButton* button = qobject_cast<QPushButton*>(QObject::sender()))
    {
    if (ctkWorkflowStep* step = d->GoToButtonToStepMap.value(button))
      {
      d->Workflow->goToStep(step->id());
      }
    }
}
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2011 Francois Beaune
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "colorentity.h"

// appleseed.renderer headers.
#include "renderer/modeling/color/wavelengths.h"

// appleseed.foundation headers.
#include "foundation/utility/containers/dictionary.h"
#include "foundation/utility/containers/specializedarrays.h"

using namespace foundation;
using namespace std;

namespace renderer
{

//
// ColorEntity class implementation.
//

struct ColorEntity::Impl
{
    ColorValueArray     m_values;
    ColorValueArray     m_alpha;
    ColorSpace          m_color_space;
    Vector2f            m_wavelength_range;
    float               m_multiplier;
};

namespace
{
    const UniqueID g_class_uid = new_guid();

    const char* color_space_name(const ColorSpace color_space)
    {
        switch (color_space)
        {
          case ColorSpaceLinearRGB:     return "linear_rgb";
          case ColorSpaceSRGB:          return "srgb";
          case ColorSpaceCIEXYZ:        return "ciexyz";
          case ColorSpaceSpectral:      return "spectral";
          default:                      return "";
        }
    }
}

ColorEntity::ColorEntity(
    const char*             name,
    const ParamArray&       params)
  : Entity(g_class_uid, params)
  , impl(new Impl())
{
    set_name(name);

    extract_parameters();
    extract_values();

    check_validity();
}

ColorEntity::ColorEntity(
    const char*             name,
    const ParamArray&       params,
    const ColorValueArray&  values)
  : Entity(g_class_uid, params)
  , impl(new Impl())
{
    set_name(name);

    extract_parameters();

    impl->m_values = values;
    impl->m_alpha.push_back(1.0f);

    check_validity();
}

ColorEntity::ColorEntity(
    const char*             name,
    const ParamArray&       params,
    const ColorValueArray&  values,
    const ColorValueArray&  alpha)
  : Entity(g_class_uid, params)
  , impl(new Impl())
{
    set_name(name);

    extract_parameters();

    impl->m_values = values;
    impl->m_alpha = alpha;

    check_validity();
}

ColorEntity::~ColorEntity()
{
    delete impl;
}

void ColorEntity::extract_parameters()
{
    // Retrieve the color space.
    const string color_space = m_params.get_required<string>("color_space", "linear_rgb");
    if (color_space == "linear_rgb")
        impl->m_color_space = ColorSpaceLinearRGB;
    else if (color_space == "srgb")
        impl->m_color_space = ColorSpaceSRGB;
    else if (color_space == "ciexyz")
        impl->m_color_space = ColorSpaceCIEXYZ;
    else if (color_space == "spectral")
        impl->m_color_space = ColorSpaceSpectral;
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value \"%s\" for parameter \"color_space\", "
            "using default value \"linear_rgb\"",
            color_space.c_str());
        impl->m_color_space = ColorSpaceLinearRGB;
    }

    // For the spectral color space, retrieve the wavelength range.
    if (impl->m_color_space == ColorSpaceSpectral)
    {
        const Vector2f DefaultWavelengthRange(LowWavelength, HighWavelength);
        impl->m_wavelength_range =
            m_params.get_required<Vector2f>(
                "wavelength_range",
                DefaultWavelengthRange);

        if (impl->m_wavelength_range[0] < 0.0 ||
            impl->m_wavelength_range[1] < 0.0 ||
            impl->m_wavelength_range[0] > impl->m_wavelength_range[1])
        {
            RENDERER_LOG_ERROR(
                "invalid value \"%f %f\" for parameter \"%s\", "
                "using default value \"%f %f\"",
                impl->m_wavelength_range[0],
                impl->m_wavelength_range[1],
                "wavelength_range",
                DefaultWavelengthRange[0],
                DefaultWavelengthRange[1]);

            impl->m_wavelength_range = DefaultWavelengthRange;
        }
    }
    else
    {
        impl->m_wavelength_range[0] =
        impl->m_wavelength_range[1] = 0.0f;
    }

    // Retrieve multiplier.
    impl->m_multiplier = m_params.get_optional<float>("multiplier", 1.0f);
}

void ColorEntity::extract_values()
{
    ColorValueArray black;
    black.push_back(0.0f);

    impl->m_values = m_params.get_required("color", black);

    ColorValueArray opaque;
    opaque.push_back(1.0f);

    impl->m_alpha = m_params.get_optional("alpha", opaque);
}

void ColorEntity::check_validity()
{
    // Check the number of color values.
    if (impl->m_color_space == ColorSpaceSpectral)
    {
        if (impl->m_values.empty())
        {
            RENDERER_LOG_ERROR("1 or more values required for \"spectral\" color space, got 0");
        }
    }
    else
    {
        if (impl->m_values.size() != 1 && impl->m_values.size() != 3)
        {
            RENDERER_LOG_ERROR(
                "1 or 3 values required for \"%s\" color space, got " FMT_SIZE_T,
                color_space_name(impl->m_color_space),
                impl->m_values.size());
        }
    }
}

void ColorEntity::release()
{
    delete this;
}

const ColorValueArray& ColorEntity::get_values() const
{
    return impl->m_values;
}

const ColorValueArray& ColorEntity::get_alpha() const
{
    return impl->m_alpha;
}

ColorSpace ColorEntity::get_color_space() const
{
    return impl->m_color_space;
}

const Vector2f& ColorEntity::get_wavelength_range() const
{
    assert(impl->m_color_space == ColorSpaceSpectral);
    return impl->m_wavelength_range;
}

float ColorEntity::get_multiplier() const
{
    return impl->m_multiplier;
}

//
// ColorEntityFactory class implementation.
//

DictionaryArray ColorEntityFactory::get_widget_definitions()
{
    DictionaryArray definitions;

    definitions.push_back(
        Dictionary()
            .insert("name", "color_space")
            .insert("label", "Color Space")
            .insert("widget", "dropdown_list")
            .insert("dropdown_items",
                Dictionary()
                    .insert("Linear RGB", "linear_rgb")
                    .insert("sRGB", "srgb")
                    .insert("CIE XYZ", "ciexyz")
                    .insert("Spectral", "spectral"))
            .insert("use", "required")
            .insert("default", "linear_rgb")
/*          .insert("on_change", "rebuild_form")*/);

    definitions.push_back(
        Dictionary()
            .insert("name", "wavelength_range")
            .insert("label", "Wavelength Range")
            .insert("widget", "text_box")
            .insert("default", "400.0 700.0")
            .insert("use", "optional"));

    definitions.push_back(
        Dictionary()
            .insert("name", "color")
            .insert("label", "Color")
            .insert("widget", "color_picker")
            .insert("default", "0.0 0.0 0.0")
            .insert("use", "required"));

    definitions.push_back(
        Dictionary()
            .insert("name", "alpha")
            .insert("label", "Alpha")
            .insert("widget", "text_box")
            .insert("default", "1.0")
            .insert("use", "optional"));

    definitions.push_back(
        Dictionary()
            .insert("name", "multiplier")
            .insert("label", "Multiplier")
            .insert("widget", "text_box")
            .insert("default", "1.0")
            .insert("use", "optional"));

    return definitions;
}

auto_release_ptr<ColorEntity> ColorEntityFactory::create(
    const char*             name,
    const ParamArray&       params)
{
    return
        auto_release_ptr<ColorEntity>(
            new ColorEntity(name, params));
}

auto_release_ptr<ColorEntity> ColorEntityFactory::create(
    const char*             name,
    const ParamArray&       params,
    const ColorValueArray&  values)
{
    return
        auto_release_ptr<ColorEntity>(
            new ColorEntity(name, params, values));
}

auto_release_ptr<ColorEntity> ColorEntityFactory::create(
    const char*             name,
    const ParamArray&       params,
    const ColorValueArray&  values,
    const ColorValueArray&  alpha)
{
    return
        auto_release_ptr<ColorEntity>(
            new ColorEntity(name, params, values, alpha));
}

}   // namespace renderer
<commit_msg>switched the default color space for color entities from linear RGB to sRGB.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2011 Francois Beaune
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "colorentity.h"

// appleseed.renderer headers.
#include "renderer/modeling/color/wavelengths.h"

// appleseed.foundation headers.
#include "foundation/utility/containers/dictionary.h"
#include "foundation/utility/containers/specializedarrays.h"

using namespace foundation;
using namespace std;

namespace renderer
{

//
// ColorEntity class implementation.
//

struct ColorEntity::Impl
{
    ColorValueArray     m_values;
    ColorValueArray     m_alpha;
    ColorSpace          m_color_space;
    Vector2f            m_wavelength_range;
    float               m_multiplier;
};

namespace
{
    const UniqueID g_class_uid = new_guid();

    const char* color_space_name(const ColorSpace color_space)
    {
        switch (color_space)
        {
          case ColorSpaceLinearRGB:     return "linear_rgb";
          case ColorSpaceSRGB:          return "srgb";
          case ColorSpaceCIEXYZ:        return "ciexyz";
          case ColorSpaceSpectral:      return "spectral";
          default:                      return "";
        }
    }
}

ColorEntity::ColorEntity(
    const char*             name,
    const ParamArray&       params)
  : Entity(g_class_uid, params)
  , impl(new Impl())
{
    set_name(name);

    extract_parameters();
    extract_values();

    check_validity();
}

ColorEntity::ColorEntity(
    const char*             name,
    const ParamArray&       params,
    const ColorValueArray&  values)
  : Entity(g_class_uid, params)
  , impl(new Impl())
{
    set_name(name);

    extract_parameters();

    impl->m_values = values;
    impl->m_alpha.push_back(1.0f);

    check_validity();
}

ColorEntity::ColorEntity(
    const char*             name,
    const ParamArray&       params,
    const ColorValueArray&  values,
    const ColorValueArray&  alpha)
  : Entity(g_class_uid, params)
  , impl(new Impl())
{
    set_name(name);

    extract_parameters();

    impl->m_values = values;
    impl->m_alpha = alpha;

    check_validity();
}

ColorEntity::~ColorEntity()
{
    delete impl;
}

void ColorEntity::extract_parameters()
{
    // Retrieve the color space.
    const ColorSpace DefaultColorSpace = ColorSpaceSRGB;
    const char* DefaultColorSpaceName = color_space_name(DefaultColorSpace);
    const string color_space = m_params.get_required<string>("color_space", DefaultColorSpaceName);
    if (color_space == "linear_rgb")
        impl->m_color_space = ColorSpaceLinearRGB;
    else if (color_space == "srgb")
        impl->m_color_space = ColorSpaceSRGB;
    else if (color_space == "ciexyz")
        impl->m_color_space = ColorSpaceCIEXYZ;
    else if (color_space == "spectral")
        impl->m_color_space = ColorSpaceSpectral;
    else
    {
        RENDERER_LOG_ERROR(
            "invalid value \"%s\" for parameter \"color_space\", "
            "using default value \"%s\"",
            color_space.c_str(),
            DefaultColorSpaceName);
        impl->m_color_space = DefaultColorSpace;
    }

    // For the spectral color space, retrieve the wavelength range.
    if (impl->m_color_space == ColorSpaceSpectral)
    {
        const Vector2f DefaultWavelengthRange(LowWavelength, HighWavelength);
        impl->m_wavelength_range =
            m_params.get_required<Vector2f>(
                "wavelength_range",
                DefaultWavelengthRange);

        if (impl->m_wavelength_range[0] < 0.0 ||
            impl->m_wavelength_range[1] < 0.0 ||
            impl->m_wavelength_range[0] > impl->m_wavelength_range[1])
        {
            RENDERER_LOG_ERROR(
                "invalid value \"%f %f\" for parameter \"%s\", "
                "using default value \"%f %f\"",
                impl->m_wavelength_range[0],
                impl->m_wavelength_range[1],
                "wavelength_range",
                DefaultWavelengthRange[0],
                DefaultWavelengthRange[1]);

            impl->m_wavelength_range = DefaultWavelengthRange;
        }
    }
    else
    {
        impl->m_wavelength_range[0] =
        impl->m_wavelength_range[1] = 0.0f;
    }

    // Retrieve multiplier.
    impl->m_multiplier = m_params.get_optional<float>("multiplier", 1.0f);
}

void ColorEntity::extract_values()
{
    ColorValueArray black;
    black.push_back(0.0f);

    impl->m_values = m_params.get_required("color", black);

    ColorValueArray opaque;
    opaque.push_back(1.0f);

    impl->m_alpha = m_params.get_optional("alpha", opaque);
}

void ColorEntity::check_validity()
{
    // Check the number of color values.
    if (impl->m_color_space == ColorSpaceSpectral)
    {
        if (impl->m_values.empty())
        {
            RENDERER_LOG_ERROR("1 or more values required for \"spectral\" color space, got 0");
        }
    }
    else
    {
        if (impl->m_values.size() != 1 && impl->m_values.size() != 3)
        {
            RENDERER_LOG_ERROR(
                "1 or 3 values required for \"%s\" color space, got " FMT_SIZE_T,
                color_space_name(impl->m_color_space),
                impl->m_values.size());
        }
    }
}

void ColorEntity::release()
{
    delete this;
}

const ColorValueArray& ColorEntity::get_values() const
{
    return impl->m_values;
}

const ColorValueArray& ColorEntity::get_alpha() const
{
    return impl->m_alpha;
}

ColorSpace ColorEntity::get_color_space() const
{
    return impl->m_color_space;
}

const Vector2f& ColorEntity::get_wavelength_range() const
{
    assert(impl->m_color_space == ColorSpaceSpectral);
    return impl->m_wavelength_range;
}

float ColorEntity::get_multiplier() const
{
    return impl->m_multiplier;
}

//
// ColorEntityFactory class implementation.
//

DictionaryArray ColorEntityFactory::get_widget_definitions()
{
    DictionaryArray definitions;

    definitions.push_back(
        Dictionary()
            .insert("name", "color_space")
            .insert("label", "Color Space")
            .insert("widget", "dropdown_list")
            .insert("dropdown_items",
                Dictionary()
                    .insert("Linear RGB", "linear_rgb")
                    .insert("sRGB", "srgb")
                    .insert("CIE XYZ", "ciexyz")
                    .insert("Spectral", "spectral"))
            .insert("use", "required")
            .insert("default", "srgb")
/*          .insert("on_change", "rebuild_form")*/);

    definitions.push_back(
        Dictionary()
            .insert("name", "wavelength_range")
            .insert("label", "Wavelength Range")
            .insert("widget", "text_box")
            .insert("default", "400.0 700.0")
            .insert("use", "optional"));

    definitions.push_back(
        Dictionary()
            .insert("name", "color")
            .insert("label", "Color")
            .insert("widget", "color_picker")
            .insert("default", "0.0 0.0 0.0")
            .insert("use", "required"));

    definitions.push_back(
        Dictionary()
            .insert("name", "alpha")
            .insert("label", "Alpha")
            .insert("widget", "text_box")
            .insert("default", "1.0")
            .insert("use", "optional"));

    definitions.push_back(
        Dictionary()
            .insert("name", "multiplier")
            .insert("label", "Multiplier")
            .insert("widget", "text_box")
            .insert("default", "1.0")
            .insert("use", "optional"));

    return definitions;
}

auto_release_ptr<ColorEntity> ColorEntityFactory::create(
    const char*             name,
    const ParamArray&       params)
{
    return
        auto_release_ptr<ColorEntity>(
            new ColorEntity(name, params));
}

auto_release_ptr<ColorEntity> ColorEntityFactory::create(
    const char*             name,
    const ParamArray&       params,
    const ColorValueArray&  values)
{
    return
        auto_release_ptr<ColorEntity>(
            new ColorEntity(name, params, values));
}

auto_release_ptr<ColorEntity> ColorEntityFactory::create(
    const char*             name,
    const ParamArray&       params,
    const ColorValueArray&  values,
    const ColorValueArray&  alpha)
{
    return
        auto_release_ptr<ColorEntity>(
            new ColorEntity(name, params, values, alpha));
}

}   // namespace renderer
<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// logger_configuration.cpp
//
// Identification: src/backend/benchmark/logger/logger_configuration.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <iomanip>
#include <algorithm>
#include <sys/stat.h>

#include "backend/common/exception.h"
#include "backend/common/logger.h"
#include "backend/benchmark/logger/logger_configuration.h"
#include "backend/benchmark/ycsb/ycsb_configuration.h"
#include "backend/benchmark/tpcc/tpcc_configuration.h"

namespace peloton {
namespace benchmark {
namespace logger {

void Usage(FILE* out) {
  fprintf(out,
          "Command line options :  logger <options> \n"
          "   -h --help              :  Print help message \n"
          "   -a --asynchronous-mode :  Asynchronous mode \n"
          "   -e --experiment-type   :  Experiment Type \n"
          "   -f --data-file-size    :  Data file size (MB) \n"
          "   -l --logging-type      :  Logging type \n"
          "   -n --nvm-latency       :  NVM latency \n"
          "   -p --pcommit-latency   :  pcommit latency \n"
          "   -v --flush-mode        :  Flush mode \n"
          "   -w --commit-interval   :  Group commit interval \n"
          "   -y --benchmark-type    :  Benchmark type \n"
  );
}

static struct option opts[] = {
    {"asynchronous_mode", optional_argument, NULL, 'a'},
    {"experiment-type", optional_argument, NULL, 'e'},
    {"data-file-size", optional_argument, NULL, 'f'},
    {"logging-type", optional_argument, NULL, 'l'},
    {"nvm-latency", optional_argument, NULL, 'n'},
    {"pcommit-latency", optional_argument, NULL, 'p'},
    {"skew", optional_argument, NULL, 's'},
    {"flush-mode", optional_argument, NULL, 'v'},
    {"commit-interval", optional_argument, NULL, 'w'},
    {"benchmark-type", optional_argument, NULL, 'y'},
    {NULL, 0, NULL, 0}};

static void ValidateLoggingType(const configuration& state) {
  if (state.logging_type <= LOGGING_TYPE_INVALID) {
    LOG_ERROR("Invalid logging_type :: %d", state.logging_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("Logging_type :: %s", LoggingTypeToString(state.logging_type).c_str());
}

std::string BenchmarkTypeToString(BenchmarkType type) {
  switch (type) {
    case BENCHMARK_TYPE_INVALID:
      return "INVALID";

    case BENCHMARK_TYPE_YCSB:
      return "YCSB";
    case BENCHMARK_TYPE_TPCC:
      return "TPCC";

    default:
      LOG_ERROR("Invalid benchmark_type :: %d", type);
      exit(EXIT_FAILURE);
  }
  return "INVALID";
}

std::string ExperimentTypeToString(ExperimentType type) {
  switch (type) {
    case EXPERIMENT_TYPE_INVALID:
      return "INVALID";

    case EXPERIMENT_TYPE_THROUGHPUT:
      return "THROUGHPUT";
    case EXPERIMENT_TYPE_RECOVERY:
      return "RECOVERY";
    case EXPERIMENT_TYPE_STORAGE:
      return "STORAGE";
    case EXPERIMENT_TYPE_LATENCY:
      return "LATENCY";

    default:
      LOG_ERROR("Invalid experiment_type :: %d", type);
      exit(EXIT_FAILURE);
  }

  return "INVALID";
}

std::string AsynchronousTypeToString(AsynchronousType type) {
  switch (type) {
    case ASYNCHRONOUS_TYPE_INVALID:
      return "INVALID";

    case ASYNCHRONOUS_TYPE_SYNC:
      return "SYNC";
    case ASYNCHRONOUS_TYPE_ASYNC:
      return "ASYNC";
    case ASYNCHRONOUS_TYPE_DISABLED:
      return "DISABLED";

    default:
      LOG_ERROR("Invalid asynchronous_mode :: %d", type);
      exit(EXIT_FAILURE);
  }

  return "INVALID";
}

static void ValidateBenchmarkType(
    const configuration& state) {
  if (state.benchmark_type <= 0 || state.benchmark_type > 3) {
    LOG_ERROR("Invalid benchmark_type :: %d", state.benchmark_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "benchmark_type", BenchmarkTypeToString(state.benchmark_type).c_str());
}

static void ValidateDataFileSize(
    const configuration& state) {
  if (state.data_file_size <= 0) {
    LOG_ERROR("Invalid data_file_size :: %lu", state.data_file_size);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("data_file_size :: %lu", state.data_file_size);
}

static void ValidateExperimentType(
    const configuration& state) {
  if (state.experiment_type < 0 || state.experiment_type > 4) {
    LOG_ERROR("Invalid experiment_type :: %d", state.experiment_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "experiment_type", ExperimentTypeToString(state.experiment_type).c_str());
}

static void ValidateWaitTimeout(const configuration& state) {
  if (state.wait_timeout < 0) {
    LOG_ERROR("Invalid wait_timeout :: %d", state.wait_timeout);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("wait_timeout :: %d", state.wait_timeout);
}

static void ValidateFlushMode(
    const configuration& state) {
  if (state.flush_mode <= 0 || state.flush_mode >= 3) {
    LOG_ERROR("Invalid flush_mode :: %d", state.flush_mode);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("flush_mode :: %d", state.flush_mode);
}

static void ValidateAsynchronousMode(
    const configuration& state) {
  if (state.asynchronous_mode <= ASYNCHRONOUS_TYPE_INVALID ||
      state.asynchronous_mode > ASYNCHRONOUS_TYPE_DISABLED) {
    LOG_ERROR("Invalid asynchronous_mode :: %d", state.asynchronous_mode);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "asynchronous_mode", AsynchronousTypeToString(state.asynchronous_mode).c_str());
}

static void ValidateNVMLatency(
    const configuration& state) {
  if (state.nvm_latency < 0) {
    LOG_ERROR("Invalid nvm_latency :: %d", state.nvm_latency);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("nvm_latency :: %d", state.nvm_latency);
}

static void ValidatePCOMMITLatency(
    const configuration& state) {
  if (state.pcommit_latency < 0) {
    LOG_ERROR("Invalid pcommit_latency :: %d", state.pcommit_latency);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("pcommit_latency :: %d", state.pcommit_latency);
}

static void ValidateLogFileDir(
    configuration& state) {
  struct stat data_stat;

  // Assign log file dir based on logging type
  switch (state.logging_type) {
    // Log file on NVM
    case LOGGING_TYPE_NVM_WAL:
    case LOGGING_TYPE_NVM_WBL: {
      int status = stat(NVM_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = NVM_DIR;
      }
    } break;

    // Log file on SSD
    case LOGGING_TYPE_SSD_WAL:
    case LOGGING_TYPE_SSD_WBL: {
      int status = stat(SSD_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = SSD_DIR;
      }
    } break;

    // Log file on HDD
    case LOGGING_TYPE_HDD_WAL:
    case LOGGING_TYPE_HDD_WBL: {
      int status = stat(HDD_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = HDD_DIR;
      }
    } break;

    case LOGGING_TYPE_INVALID:
    default: {
      int status = stat(TMP_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = TMP_DIR;
      } else {
        throw Exception("Could not find temp directory : " +
                        std::string(TMP_DIR));
      }
    } break;
  }

  LOG_INFO("log_file_dir :: %s", state.log_file_dir.c_str());
}

void ParseArguments(int argc, char* argv[], configuration& state) {

  // Default Logger Values
  state.logging_type = LOGGING_TYPE_NVM_WAL;
  state.log_file_dir = TMP_DIR;
  state.data_file_size = 512;

  state.experiment_type = EXPERIMENT_TYPE_THROUGHPUT;
  state.wait_timeout = 200;
  state.benchmark_type = BENCHMARK_TYPE_YCSB;
  state.flush_mode = 2;
  state.nvm_latency = 0;
  state.pcommit_latency = 0;
  state.asynchronous_mode = ASYNCHRONOUS_TYPE_SYNC;

  // Default YCSB Values
  ycsb::state.scale_factor = 1;
  ycsb::state.duration = 1000;
  ycsb::state.column_count = 10;
  ycsb::state.update_ratio = 0.5;
  ycsb::state.backend_count = 2;

  // Default Values
  tpcc::state.warehouse_count = 2;  // 10
  tpcc::state.duration = 1000;
  tpcc::state.backend_count = 2;

  // Parse args
  while (1) {
    int idx = 0;
    // logger - a:e:f:hl:n:p:v:w:y:
    // ycsb   - b:c:d:k:u:
    // tpcc   - b:d:k:
    int c = getopt_long(argc, argv, "a:e:f:hl:n:p:v:w:y:b:c:d:k:u:", opts, &idx);

    if (c == -1) break;

    switch (c) {
      case 'a':
        state.asynchronous_mode = (AsynchronousType) atoi(optarg);
        break;
      case 'e':
        state.experiment_type = (ExperimentType)atoi(optarg);
        break;
      case 'f':
        state.data_file_size = atoi(optarg);
        break;
      case 'l':
        state.logging_type = (LoggingType)atoi(optarg);
        break;
      case 'n':
        state.nvm_latency = atoi(optarg);
        break;
      case 'p':
        state.pcommit_latency = atoi(optarg);
        break;
      case 'v':
        state.flush_mode = atoi(optarg);
        break;
      case 'w':
        state.wait_timeout = atoi(optarg);
        break;
      case 'y':
        state.benchmark_type = (BenchmarkType)atoi(optarg);
        break;

        // YCSB
      case 'b':
        ycsb::state.backend_count = atoi(optarg);
        tpcc::state.backend_count = atoi(optarg);
        break;
      case 'c':
        ycsb::state.column_count = atoi(optarg);
        break;
      case 'd':
        ycsb::state.duration = atoi(optarg);
        tpcc::state.duration = atoi(optarg);
        break;
      case 'k':
        ycsb::state.scale_factor = atoi(optarg);
        tpcc::state.warehouse_count = atoi(optarg);
        break;
      case 'u':
        ycsb::state.update_ratio = atof(optarg);
        break;

      case 'h':
        Usage(stderr);
        ycsb::Usage(stderr);
        exit(EXIT_FAILURE);
        break;

      default:
        fprintf(stderr, "\nUnknown option: -%c-\n", c);
        Usage(stderr);
        exit(EXIT_FAILURE);
        break;
    }
  }

  // Print Logger configuration
  ValidateLoggingType(state);
  ValidateExperimentType(state);
  ValidateAsynchronousMode(state);
  ValidateBenchmarkType(state);
  ValidateDataFileSize(state);
  ValidateLogFileDir(state);
  ValidateWaitTimeout(state);
  ValidateFlushMode(state);
  ValidateNVMLatency(state);
  ValidatePCOMMITLatency(state);

  // Print YCSB configuration
  if(state.benchmark_type == BENCHMARK_TYPE_YCSB) {
    ycsb::ValidateScaleFactor(ycsb::state);
    ycsb::ValidateColumnCount(ycsb::state);
    ycsb::ValidateUpdateRatio(ycsb::state);
    ycsb::ValidateBackendCount(ycsb::state);
    ycsb::ValidateDuration(ycsb::state);
  }
  // Print TPCC configuration
  else if(state.benchmark_type == BENCHMARK_TYPE_TPCC){
    tpcc::ValidateBackendCount(tpcc::state);
    tpcc::ValidateDuration(tpcc::state);
    tpcc::ValidateWarehouseCount(tpcc::state);

    // Static TPCC parameters
    tpcc::state.item_count = 10000;                    // 100000
    tpcc::state.districts_per_warehouse = 2;           // 10
    tpcc::state.customers_per_district = 300;          // 3000
    tpcc::state.new_orders_per_district = 90;          // 900

  }

}

}  // namespace logger
}  // namespace benchmark
}  // namespace peloton
<commit_msg>Updated conf<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// logger_configuration.cpp
//
// Identification: src/backend/benchmark/logger/logger_configuration.cpp
//
// Copyright (c) 2015-16, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <iomanip>
#include <algorithm>
#include <sys/stat.h>

#include "backend/common/exception.h"
#include "backend/common/logger.h"
#include "backend/benchmark/logger/logger_configuration.h"
#include "backend/benchmark/ycsb/ycsb_configuration.h"
#include "backend/benchmark/tpcc/tpcc_configuration.h"

namespace peloton {
namespace benchmark {
namespace logger {

void Usage(FILE* out) {
  fprintf(out,
          "Command line options :  logger <options> \n"
          "   -h --help              :  Print help message \n"
          "   -a --asynchronous-mode :  Asynchronous mode \n"
          "   -e --experiment-type   :  Experiment Type \n"
          "   -f --data-file-size    :  Data file size (MB) \n"
          "   -l --logging-type      :  Logging type \n"
          "   -n --nvm-latency       :  NVM latency \n"
          "   -p --pcommit-latency   :  pcommit latency \n"
          "   -v --flush-mode        :  Flush mode \n"
          "   -w --commit-interval   :  Group commit interval \n"
          "   -y --benchmark-type    :  Benchmark type \n"
  );
}

static struct option opts[] = {
    {"asynchronous_mode", optional_argument, NULL, 'a'},
    {"experiment-type", optional_argument, NULL, 'e'},
    {"data-file-size", optional_argument, NULL, 'f'},
    {"logging-type", optional_argument, NULL, 'l'},
    {"nvm-latency", optional_argument, NULL, 'n'},
    {"pcommit-latency", optional_argument, NULL, 'p'},
    {"skew", optional_argument, NULL, 's'},
    {"flush-mode", optional_argument, NULL, 'v'},
    {"commit-interval", optional_argument, NULL, 'w'},
    {"benchmark-type", optional_argument, NULL, 'y'},
    {NULL, 0, NULL, 0}};

static void ValidateLoggingType(const configuration& state) {
  if (state.logging_type <= LOGGING_TYPE_INVALID) {
    LOG_ERROR("Invalid logging_type :: %d", state.logging_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("Logging_type :: %s", LoggingTypeToString(state.logging_type).c_str());
}

std::string BenchmarkTypeToString(BenchmarkType type) {
  switch (type) {
    case BENCHMARK_TYPE_INVALID:
      return "INVALID";

    case BENCHMARK_TYPE_YCSB:
      return "YCSB";
    case BENCHMARK_TYPE_TPCC:
      return "TPCC";

    default:
      LOG_ERROR("Invalid benchmark_type :: %d", type);
      exit(EXIT_FAILURE);
  }
  return "INVALID";
}

std::string ExperimentTypeToString(ExperimentType type) {
  switch (type) {
    case EXPERIMENT_TYPE_INVALID:
      return "INVALID";

    case EXPERIMENT_TYPE_THROUGHPUT:
      return "THROUGHPUT";
    case EXPERIMENT_TYPE_RECOVERY:
      return "RECOVERY";
    case EXPERIMENT_TYPE_STORAGE:
      return "STORAGE";
    case EXPERIMENT_TYPE_LATENCY:
      return "LATENCY";

    default:
      LOG_ERROR("Invalid experiment_type :: %d", type);
      exit(EXIT_FAILURE);
  }

  return "INVALID";
}

std::string AsynchronousTypeToString(AsynchronousType type) {
  switch (type) {
    case ASYNCHRONOUS_TYPE_INVALID:
      return "INVALID";

    case ASYNCHRONOUS_TYPE_SYNC:
      return "SYNC";
    case ASYNCHRONOUS_TYPE_ASYNC:
      return "ASYNC";
    case ASYNCHRONOUS_TYPE_DISABLED:
      return "DISABLED";

    default:
      LOG_ERROR("Invalid asynchronous_mode :: %d", type);
      exit(EXIT_FAILURE);
  }

  return "INVALID";
}

static void ValidateBenchmarkType(
    const configuration& state) {
  if (state.benchmark_type <= 0 || state.benchmark_type > 3) {
    LOG_ERROR("Invalid benchmark_type :: %d", state.benchmark_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "benchmark_type", BenchmarkTypeToString(state.benchmark_type).c_str());
}

static void ValidateDataFileSize(
    const configuration& state) {
  if (state.data_file_size <= 0) {
    LOG_ERROR("Invalid data_file_size :: %lu", state.data_file_size);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("data_file_size :: %lu", state.data_file_size);
}

static void ValidateExperimentType(
    const configuration& state) {
  if (state.experiment_type < 0 || state.experiment_type > 4) {
    LOG_ERROR("Invalid experiment_type :: %d", state.experiment_type);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "experiment_type", ExperimentTypeToString(state.experiment_type).c_str());
}

static void ValidateWaitTimeout(const configuration& state) {
  if (state.wait_timeout < 0) {
    LOG_ERROR("Invalid wait_timeout :: %d", state.wait_timeout);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("wait_timeout :: %d", state.wait_timeout);
}

static void ValidateFlushMode(
    const configuration& state) {
  if (state.flush_mode <= 0 || state.flush_mode >= 3) {
    LOG_ERROR("Invalid flush_mode :: %d", state.flush_mode);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("flush_mode :: %d", state.flush_mode);
}

static void ValidateAsynchronousMode(
    const configuration& state) {
  if (state.asynchronous_mode <= ASYNCHRONOUS_TYPE_INVALID ||
      state.asynchronous_mode > ASYNCHRONOUS_TYPE_DISABLED) {
    LOG_ERROR("Invalid asynchronous_mode :: %d", state.asynchronous_mode);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("%s : %s", "asynchronous_mode", AsynchronousTypeToString(state.asynchronous_mode).c_str());
}

static void ValidateNVMLatency(
    const configuration& state) {
  if (state.nvm_latency < 0) {
    LOG_ERROR("Invalid nvm_latency :: %d", state.nvm_latency);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("nvm_latency :: %d", state.nvm_latency);
}

static void ValidatePCOMMITLatency(
    const configuration& state) {
  if (state.pcommit_latency < 0) {
    LOG_ERROR("Invalid pcommit_latency :: %d", state.pcommit_latency);
    exit(EXIT_FAILURE);
  }

  LOG_INFO("pcommit_latency :: %d", state.pcommit_latency);
}

static void ValidateLogFileDir(
    configuration& state) {
  struct stat data_stat;

  // Assign log file dir based on logging type
  switch (state.logging_type) {
    // Log file on NVM
    case LOGGING_TYPE_NVM_WAL:
    case LOGGING_TYPE_NVM_WBL: {
      int status = stat(NVM_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = NVM_DIR;
      }
    } break;

    // Log file on SSD
    case LOGGING_TYPE_SSD_WAL:
    case LOGGING_TYPE_SSD_WBL: {
      int status = stat(SSD_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = SSD_DIR;
      }
    } break;

    // Log file on HDD
    case LOGGING_TYPE_HDD_WAL:
    case LOGGING_TYPE_HDD_WBL: {
      int status = stat(HDD_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = HDD_DIR;
      }
    } break;

    case LOGGING_TYPE_INVALID:
    default: {
      int status = stat(TMP_DIR, &data_stat);
      if (status == 0 && S_ISDIR(data_stat.st_mode)) {
        state.log_file_dir = TMP_DIR;
      } else {
        throw Exception("Could not find temp directory : " +
                        std::string(TMP_DIR));
      }
    } break;
  }

  LOG_INFO("log_file_dir :: %s", state.log_file_dir.c_str());
}

void ParseArguments(int argc, char* argv[], configuration& state) {

  // Default Logger Values
  state.logging_type = LOGGING_TYPE_NVM_WAL;
  state.log_file_dir = TMP_DIR;
  state.data_file_size = 512;

  state.experiment_type = EXPERIMENT_TYPE_THROUGHPUT;
  state.wait_timeout = 200;
  state.benchmark_type = BENCHMARK_TYPE_YCSB;
  state.flush_mode = 2;
  state.nvm_latency = 0;
  state.pcommit_latency = 0;
  state.asynchronous_mode = ASYNCHRONOUS_TYPE_SYNC;

  // Default YCSB Values
  ycsb::state.scale_factor = 1;
  ycsb::state.duration = 1000;
  ycsb::state.column_count = 10;
  ycsb::state.update_ratio = 0.5;
  ycsb::state.backend_count = 2;

  // Default Values
  tpcc::state.warehouse_count = 2;  // 10
  tpcc::state.duration = 1000;
  tpcc::state.backend_count = 2;

  // Parse args
  while (1) {
    int idx = 0;
    // logger - a:e:f:hl:n:p:v:w:y:
    // ycsb   - b:c:d:k:u:
    // tpcc   - b:d:k:
    int c = getopt_long(argc, argv, "a:e:f:hl:n:p:v:w:y:b:c:d:k:u:", opts, &idx);

    if (c == -1) break;

    switch (c) {
      case 'a':
        state.asynchronous_mode = (AsynchronousType) atoi(optarg);
        break;
      case 'e':
        state.experiment_type = (ExperimentType)atoi(optarg);
        break;
      case 'f':
        state.data_file_size = atoi(optarg);
        break;
      case 'l':
        state.logging_type = (LoggingType)atoi(optarg);
        break;
      case 'n':
        state.nvm_latency = atoi(optarg);
        break;
      case 'p':
        state.pcommit_latency = atoi(optarg);
        break;
      case 'v':
        state.flush_mode = atoi(optarg);
        break;
      case 'w':
        state.wait_timeout = atoi(optarg);
        break;
      case 'y':
        state.benchmark_type = (BenchmarkType)atoi(optarg);
        break;

        // YCSB
      case 'b':
        ycsb::state.backend_count = atoi(optarg);
        tpcc::state.backend_count = atoi(optarg);
        break;
      case 'c':
        ycsb::state.column_count = atoi(optarg);
        break;
      case 'd':
        ycsb::state.duration = atoi(optarg);
        tpcc::state.duration = atoi(optarg);
        break;
      case 'k':
        ycsb::state.scale_factor = atoi(optarg);
        tpcc::state.warehouse_count = atoi(optarg);
        break;
      case 'u':
        ycsb::state.update_ratio = atof(optarg);
        break;

      case 'h':
        Usage(stderr);
        ycsb::Usage(stderr);
        exit(EXIT_FAILURE);
        break;

      default:
        fprintf(stderr, "\nUnknown option: -%c-\n", c);
        Usage(stderr);
        exit(EXIT_FAILURE);
        break;
    }
  }

  // Print Logger configuration
  ValidateLoggingType(state);
  ValidateExperimentType(state);
  ValidateAsynchronousMode(state);
  ValidateBenchmarkType(state);
  ValidateDataFileSize(state);
  ValidateLogFileDir(state);
  ValidateWaitTimeout(state);
  ValidateFlushMode(state);
  ValidateNVMLatency(state);
  ValidatePCOMMITLatency(state);

  // Print YCSB configuration
  if(state.benchmark_type == BENCHMARK_TYPE_YCSB) {
    ycsb::ValidateScaleFactor(ycsb::state);
    ycsb::ValidateColumnCount(ycsb::state);
    ycsb::ValidateUpdateRatio(ycsb::state);
    ycsb::ValidateBackendCount(ycsb::state);
    ycsb::ValidateDuration(ycsb::state);
  }
  // Print TPCC configuration
  else if(state.benchmark_type == BENCHMARK_TYPE_TPCC){
    tpcc::ValidateBackendCount(tpcc::state);
    tpcc::ValidateDuration(tpcc::state);
    tpcc::ValidateWarehouseCount(tpcc::state);

    // Static TPCC parameters
    tpcc::state.item_count = 1000;                     // 100000
    tpcc::state.districts_per_warehouse = 2;           // 10
    tpcc::state.customers_per_district = 30;           // 3000
    tpcc::state.new_orders_per_district = 9;           // 900

  }

}

}  // namespace logger
}  // namespace benchmark
}  // namespace peloton
<|endoftext|>