<commit_before>#ifndef itkGMMMLEPointSetToPointSetMetric_hxx
#define itkGMMMLEPointSetToPointSetMetric_hxx

#include "itkGMMMLEPointSetToPointSetMetric.h"

namespace itk
{
/**
 * Constructor
 */
template <typename TFixedPointSet, typename TMovingPointSet>
GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::GMMMLEPointSetToPointSetMetric()
{
}

/** Initialize the metric */
template< typename TFixedPointSet, typename TMovingPointSet >
void
GMMMLEPointSetToPointSetMetric< TFixedPointSet, TMovingPointSet >
::Initialize() throw (ExceptionObject)
{
  Superclass::Initialize();

  m_ValuesOfProbability.set_size(this->m_NumberOfFixedPoints);
}

/**
 * Get the match Measure
 */
template <typename TFixedPointSet, typename TMovingPointSet>
typename GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::MeasureType
GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::GetValue(const TransformParametersType & parameters) const
{
  this->m_Transform->SetParameters(parameters);

  // compute transformed point set
  this->m_TransformedPointSet = MovingPointSetType::New();
  for (MovingPointIterator iter = this->m_MovingPointSet->GetPoints()->Begin(); iter != this->m_MovingPointSet->GetPoints()->End(); ++iter) {
    this->m_TransformedPointSet->SetPoint(iter.Index(), this->m_Transform->TransformPoint(iter.Value()));
  }

  const double scale = 2.0 * this->m_MovingPointSetScale * this->m_MovingPointSetScale;

  MeasureType value = NumericTraits<MeasureType>::ZeroValue();

  for (FixedPointIterator fixedIter = this->m_FixedPointSet->GetPoints()->Begin(); fixedIter != this->m_FixedPointSet->GetPoints()->End(); ++fixedIter) {
    const typename FixedPointSetType::PointType fixedPoint = fixedIter.Value();
    double sum = 1.0e-05;

    for (MovingPointIterator transformedIter = this->m_TransformedPointSet->GetPoints()->Begin(); transformedIter != this->m_TransformedPointSet->GetPoints()->End(); ++transformedIter) {
      const typename MovingPointSetType::PointType transformedPoint = transformedIter.Value();
      const double distance = transformedPoint.SquaredEuclideanDistanceTo(fixedPoint);
      sum += exp(-distance / scale);
    }

    m_ValuesOfProbability[fixedIter.Index()] = sum;
    value -= log(sum);
  }

  return value;
}
/**
 * Get the Derivative Measure
 */
template <typename TFixedPointSet, typename TMovingPointSet>
void GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::GetDerivative(const TransformParametersType & parameters, DerivativeType & derivative) const
{
  itkExceptionMacro(<< "not implemented");
}

/*
 * Get both the match Measure and the Derivative Measure
 */
template <typename TFixedPointSet, typename TMovingPointSet>
void GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::GetValueAndDerivative(const TransformParametersType & parameters, MeasureType & value, DerivativeType  & derivative) const
{
  this->m_Transform->SetParameters(parameters);

  if (derivative.size() != this->m_NumberOfParameters) {
    derivative.set_size(this->m_NumberOfParameters);
  }

  // compute transformed point set
  this->m_TransformedPointSet = MovingPointSetType::New();
  for (MovingPointIterator iter = this->m_MovingPointSet->GetPoints()->Begin(); iter != this->m_MovingPointSet->GetPoints()->End(); ++iter) {
    this->m_TransformedPointSet->SetPoint(iter.Index(), this->m_Transform->TransformPoint(iter.Value()));
  }

  const double scale = 2.0 * this->m_MovingPointSetScale * this->m_MovingPointSetScale;

  value = NumericTraits<MeasureType>::ZeroValue();

  for (FixedPointIterator fixedIter = this->m_FixedPointSet->GetPoints()->Begin(); fixedIter != this->m_FixedPointSet->GetPoints()->End(); ++fixedIter) {
    const typename FixedPointSetType::PointType fixedPoint = fixedIter.Value();
    double sum = 1.0e-05;

    for (MovingPointIterator transformedIter = this->m_TransformedPointSet->GetPoints()->Begin(); transformedIter != this->m_TransformedPointSet->GetPoints()->End(); ++transformedIter) {
      const typename MovingPointSetType::PointType transformedPoint = transformedIter.Value();
      const double distance = transformedPoint.SquaredEuclideanDistanceTo(fixedPoint);
      sum += exp(-distance / scale);
    }

    m_ValuesOfProbability[fixedIter.Index()] = sum;
    value -= log(sum);
  }

  // compute the derivatives
  derivative.Fill(NumericTraits<typename DerivativeType::ValueType>::ZeroValue());
  GradientType gradient;

  for (MovingPointIterator transformedIter = this->m_TransformedPointSet->GetPoints()->Begin(); transformedIter != this->m_TransformedPointSet->GetPoints()->End(); ++transformedIter) {

    // compute gradient for the current transformed point
    const typename MovingPointSetType::PointType transformedPoint = transformedIter.Value();
    gradient.Fill(0);

    for (FixedPointIterator fixedIter = this->m_FixedPointSet->GetPoints()->Begin(); fixedIter != this->m_FixedPointSet->GetPoints()->End(); ++fixedIter) {
      const typename FixedPointSetType::PointType fixedPoint = fixedIter.Value();
      const double distance = transformedPoint.SquaredEuclideanDistanceTo(fixedPoint);
      const double expval = exp(-distance / scale);
      const double prbval = m_ValuesOfProbability[fixedIter.Index()];

      for (size_t dim = 0; dim < this->PointDimension; ++dim) {
        gradient[dim] += 2.0 * expval * (transformedPoint[dim] - fixedPoint[dim]) / (scale * prbval);
      }
    }

    // compute derivatives for the current transformed point
    this->m_Transform->ComputeJacobianWithRespectToParametersCachedTemporaries(this->m_MovingPointSet->GetPoint(transformedIter.Index()), this->m_Jacobian, this->m_JacobianCache);

    for (size_t par = 0; par < this->m_NumberOfParameters; ++par) {
      for (size_t dim = 0; dim < this->PointDimension; ++dim) {
        derivative[par] += this->m_Jacobian(dim, par) * gradient[dim];
      }
    }
  }
}
}

#endif
<commit_msg>optimize calculations<commit_after>#ifndef itkGMMMLEPointSetToPointSetMetric_hxx
#define itkGMMMLEPointSetToPointSetMetric_hxx

#include "itkGMMMLEPointSetToPointSetMetric.h"

namespace itk
{
/**
 * Constructor
 */
template <typename TFixedPointSet, typename TMovingPointSet>
GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::GMMMLEPointSetToPointSetMetric()
{
}

/** Initialize the metric */
template< typename TFixedPointSet, typename TMovingPointSet >
void
GMMMLEPointSetToPointSetMetric< TFixedPointSet, TMovingPointSet >
::Initialize() throw (ExceptionObject)
{
  Superclass::Initialize();

  m_ValuesOfProbability.set_size(this->m_NumberOfFixedPoints);
}

/**
 * Get the match Measure
 */
template <typename TFixedPointSet, typename TMovingPointSet>
typename GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::MeasureType
GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::GetValue(const TransformParametersType & parameters) const
{
  this->m_Transform->SetParameters(parameters);

  // compute transformed point set
  this->m_TransformedPointSet = MovingPointSetType::New();
  for (MovingPointIterator iter = this->m_MovingPointSet->GetPoints()->Begin(); iter != this->m_MovingPointSet->GetPoints()->End(); ++iter) {
    this->m_TransformedPointSet->SetPoint(iter.Index(), this->m_Transform->TransformPoint(iter.Value()));
  }

  const double scale = 2.0 * this->m_MovingPointSetScale * this->m_MovingPointSetScale;

  MeasureType value = NumericTraits<MeasureType>::ZeroValue();

  for (FixedPointIterator fixedIter = this->m_FixedPointSet->GetPoints()->Begin(); fixedIter != this->m_FixedPointSet->GetPoints()->End(); ++fixedIter) {
    const typename FixedPointSetType::PointType fixedPoint = fixedIter.Value();
    double sum = 1.0e-05;

    for (MovingPointIterator transformedIter = this->m_TransformedPointSet->GetPoints()->Begin(); transformedIter != this->m_TransformedPointSet->GetPoints()->End(); ++transformedIter) {
      const typename MovingPointSetType::PointType transformedPoint = transformedIter.Value();
      const double distance = transformedPoint.SquaredEuclideanDistanceTo(fixedPoint);
      sum += exp(-distance / scale);
    }

    m_ValuesOfProbability[fixedIter.Index()] = sum;
    value -= log(sum);
  }

  return value;
}
/**
 * Get the Derivative Measure
 */
template <typename TFixedPointSet, typename TMovingPointSet>
void GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::GetDerivative(const TransformParametersType & parameters, DerivativeType & derivative) const
{
  itkExceptionMacro(<< "not implemented");
}

/*
 * Get both the match Measure and the Derivative Measure
 */
template <typename TFixedPointSet, typename TMovingPointSet>
void GMMMLEPointSetToPointSetMetric<TFixedPointSet, TMovingPointSet>::GetValueAndDerivative(const TransformParametersType & parameters, MeasureType & value, DerivativeType  & derivative) const
{
  this->m_Transform->SetParameters(parameters);

  if (derivative.size() != this->m_NumberOfParameters) {
    derivative.set_size(this->m_NumberOfParameters);
  }

  // compute transformed point set
  this->m_TransformedPointSet = MovingPointSetType::New();
  for (MovingPointIterator iter = this->m_MovingPointSet->GetPoints()->Begin(); iter != this->m_MovingPointSet->GetPoints()->End(); ++iter) {
    this->m_TransformedPointSet->SetPoint(iter.Index(), this->m_Transform->TransformPoint(iter.Value()));
  }

  const double scale = 2.0 * this->m_MovingPointSetScale * this->m_MovingPointSetScale;

  value = NumericTraits<MeasureType>::ZeroValue();

  for (FixedPointIterator fixedIter = this->m_FixedPointSet->GetPoints()->Begin(); fixedIter != this->m_FixedPointSet->GetPoints()->End(); ++fixedIter) {
    const typename FixedPointSetType::PointType fixedPoint = fixedIter.Value();
    double sum = 1.0e-05;

    for (MovingPointIterator transformedIter = this->m_TransformedPointSet->GetPoints()->Begin(); transformedIter != this->m_TransformedPointSet->GetPoints()->End(); ++transformedIter) {
      const typename MovingPointSetType::PointType transformedPoint = transformedIter.Value();
      const double distance = transformedPoint.SquaredEuclideanDistanceTo(fixedPoint);
      sum += exp(-distance / scale);
    }

    m_ValuesOfProbability[fixedIter.Index()] = sum;
    value -= log(sum);
  }

  // compute the derivatives
  derivative.Fill(NumericTraits<typename DerivativeType::ValueType>::ZeroValue());
  GradientType gradient;

  for (MovingPointIterator transformedIter = this->m_TransformedPointSet->GetPoints()->Begin(); transformedIter != this->m_TransformedPointSet->GetPoints()->End(); ++transformedIter) {

    // compute gradient for the current transformed point
    const typename MovingPointSetType::PointType transformedPoint = transformedIter.Value();
    gradient.Fill(0);

    for (FixedPointIterator fixedIter = this->m_FixedPointSet->GetPoints()->Begin(); fixedIter != this->m_FixedPointSet->GetPoints()->End(); ++fixedIter) {
      const typename FixedPointSetType::PointType fixedPoint = fixedIter.Value();
      const double distance = transformedPoint.SquaredEuclideanDistanceTo(fixedPoint);
      const double expval = exp(-distance / scale);
      const double prbval = m_ValuesOfProbability[fixedIter.Index()];

      for (size_t dim = 0; dim < this->PointDimension; ++dim) {
        gradient[dim] += expval * (transformedPoint[dim] - fixedPoint[dim]) / prbval;
      }
    }

    // compute derivatives for the current transformed point
    this->m_Transform->ComputeJacobianWithRespectToParametersCachedTemporaries(this->m_MovingPointSet->GetPoint(transformedIter.Index()), this->m_Jacobian, this->m_JacobianCache);

    for (size_t dim = 0; dim < this->PointDimension; ++dim) {
      gradient[dim] *= (2.0 / scale);

      for (size_t par = 0; par < this->m_NumberOfParameters; ++par) {
        derivative[par] += this->m_Jacobian(dim, par) * gradient[dim];
      }
    }
  }
}
}

#endif
<|endoftext|>


<commit_before>#include <boost/program_options.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>

#include <mapnik/utils.hpp>
#include <mapnik/load_map.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/datasource_cache.hpp>

#include "avecado.hpp"
#include "http_server/server.hpp"
#include "config.h"

namespace bpo = boost::program_options;
using boost::asio::ip::tcp;

int main(int argc, char *argv[]) {
  server_options srv_opts;
  std::string fonts_dir, input_plugins_dir;

  bpo::options_description options(
    "Avecado " VERSION "\n"
    "\n"
    "  Usage: avecado_server [options] <map-file> <port> <num-threads>\n"
    "\n");

  options.add_options()
    ("help,h", "Print this help message.")
    ("path-multiplier,p", bpo::value<unsigned int>(&srv_opts.path_multiplier)->default_value(16),
     "Create a tile with coordinates multiplied by this constant to get sub-pixel "
     "accuracy.")
    ("buffer-size,b", bpo::value<int>(&srv_opts.buffer_size)->default_value(0),
     "Number of pixels around the tile to buffer in order to allow for features "
     "whose rendering effects extend beyond the geometric extent.")
    ("scale_factor,s", bpo::value<double>(&srv_opts.scale_factor)->default_value(1.0),
     "Scale factor to multiply style values by.")
    ("offset-x", bpo::value<unsigned int>(&srv_opts.offset_x)->default_value(0),
     "Offset added to tile geometry x coordinates.")
    ("offset-y", bpo::value<unsigned int>(&srv_opts.offset_y)->default_value(0),
     "Offset added to tile geometry y coordinates.")
    ("tolerance,t", bpo::value<unsigned int>(&srv_opts.tolerance)->default_value(1),
     "Tolerance used to simplify output geometry.")
    ("image-format,f", bpo::value<std::string>(&srv_opts.image_format)->default_value("jpeg"),
     "Image file format used for embedding raster layers.")
    ("scaling-method,m", bpo::value<std::string>()->default_value("near"),
     "Method used to re-sample raster layers.")
    ("scale-denominator,d", bpo::value<double>(&srv_opts.scale_denominator)->default_value(0.0),
     "Override for scale denominator. A value of 0 means to use the sensible default "
     "which Mapnik will generate from the tile context.")
    ("fonts", bpo::value<std::string>(&fonts_dir)->default_value(MAPNIK_DEFAULT_FONT_DIR),
     "Directory to tell Mapnik to look in for fonts.")
    ("input-plugins", bpo::value<std::string>(&input_plugins_dir)
     ->default_value(MAPNIK_DEFAULT_INPUT_PLUGIN_DIR),
     "Directory to tell Mapnik to look in for input plugins.")
    ("thread-hint", bpo::value<unsigned short>(&srv_opts.thread_hint)->default_value(1),
     "Hint at the number of asynchronous "
     "requests the server should be able to service.")
    // positional arguments
    ("map-file", bpo::value<std::string>(&srv_opts.map_file), "Mapnik XML input file.")
    ("port", bpo::value<std::string>(&srv_opts.port), "Port upon which the server will listen.")
    ;

  bpo::positional_options_description pos_options;
  pos_options
    .add("map-file", 1)
    .add("port", 1)
    ;

  bpo::variables_map vm;

  try {
    bpo::store(bpo::command_line_parser(argc,argv)
           .options(options)
           .positional(pos_options)
           .run(),
           vm);
    bpo::notify(vm);

  } catch (std::exception &e) {
    std::cerr << "Unable to parse command line options because: " << e.what() << "\n"
			  << "This is a bug, please report it at " PACKAGE_BUGREPORT << "\n";
    return EXIT_FAILURE;
  }

  if (vm.count("help")) {
    std::cout << options << "\n";
    return EXIT_SUCCESS;
  }

  // argument checking and verification
  for (auto arg : {"map-file", "port"}) {
    if (vm.count(arg) == 0) {
      std::cerr << "The <" << arg << "> argument was not provided, but is mandatory\n\n";
      std::cerr << options << "\n";
      return EXIT_FAILURE;
    }
  }

  if (vm.count("scaling-method")) {
    std::string method_str(vm["scaling-method"].as<std::string>());

    boost::optional<mapnik::scaling_method_e> method =
      mapnik::scaling_method_from_string(method_str);

    if (!method) {
      std::cerr << "The string \"" << method_str << "\" was not recognised as a "
          << "valid scaling method by Mapnik.\n";
      return EXIT_FAILURE;
    }

    srv_opts.scaling_method = *method;

  } else {
    // default option
    srv_opts.scaling_method = mapnik::SCALING_NEAR;
  }

  //start up the server
  try {
    // try to register fonts and input plugins
    mapnik::freetype_engine::register_fonts(fonts_dir);
    mapnik::datasource_cache::instance().register_datasources(input_plugins_dir);

    // start the server running
    http::server3::server server("*", srv_opts);
    server.run();

    // TODO: how to pause this thread?
    while (true) {
      sleep(60);
    }

    server.stop();

  } catch (std::exception& e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return EXIT_SUCCESS;
}
<commit_msg>Fixed documentation string.<commit_after>#include <boost/program_options.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>

#include <mapnik/utils.hpp>
#include <mapnik/load_map.hpp>
#include <mapnik/font_engine_freetype.hpp>
#include <mapnik/datasource_cache.hpp>

#include "avecado.hpp"
#include "http_server/server.hpp"
#include "config.h"

namespace bpo = boost::program_options;
using boost::asio::ip::tcp;

int main(int argc, char *argv[]) {
  server_options srv_opts;
  std::string fonts_dir, input_plugins_dir;

  bpo::options_description options(
    "Avecado " VERSION "\n"
    "\n"
    "  Usage: avecado_server [options] <map-file> <port>\n"
    "\n");

  options.add_options()
    ("help,h", "Print this help message.")
    ("path-multiplier,p", bpo::value<unsigned int>(&srv_opts.path_multiplier)->default_value(16),
     "Create a tile with coordinates multiplied by this constant to get sub-pixel "
     "accuracy.")
    ("buffer-size,b", bpo::value<int>(&srv_opts.buffer_size)->default_value(0),
     "Number of pixels around the tile to buffer in order to allow for features "
     "whose rendering effects extend beyond the geometric extent.")
    ("scale_factor,s", bpo::value<double>(&srv_opts.scale_factor)->default_value(1.0),
     "Scale factor to multiply style values by.")
    ("offset-x", bpo::value<unsigned int>(&srv_opts.offset_x)->default_value(0),
     "Offset added to tile geometry x coordinates.")
    ("offset-y", bpo::value<unsigned int>(&srv_opts.offset_y)->default_value(0),
     "Offset added to tile geometry y coordinates.")
    ("tolerance,t", bpo::value<unsigned int>(&srv_opts.tolerance)->default_value(1),
     "Tolerance used to simplify output geometry.")
    ("image-format,f", bpo::value<std::string>(&srv_opts.image_format)->default_value("jpeg"),
     "Image file format used for embedding raster layers.")
    ("scaling-method,m", bpo::value<std::string>()->default_value("near"),
     "Method used to re-sample raster layers.")
    ("scale-denominator,d", bpo::value<double>(&srv_opts.scale_denominator)->default_value(0.0),
     "Override for scale denominator. A value of 0 means to use the sensible default "
     "which Mapnik will generate from the tile context.")
    ("fonts", bpo::value<std::string>(&fonts_dir)->default_value(MAPNIK_DEFAULT_FONT_DIR),
     "Directory to tell Mapnik to look in for fonts.")
    ("input-plugins", bpo::value<std::string>(&input_plugins_dir)
     ->default_value(MAPNIK_DEFAULT_INPUT_PLUGIN_DIR),
     "Directory to tell Mapnik to look in for input plugins.")
    ("thread-hint", bpo::value<unsigned short>(&srv_opts.thread_hint)->default_value(1),
     "Hint at the number of asynchronous "
     "requests the server should be able to service.")
    // positional arguments
    ("map-file", bpo::value<std::string>(&srv_opts.map_file), "Mapnik XML input file.")
    ("port", bpo::value<std::string>(&srv_opts.port), "Port upon which the server will listen.")
    ;

  bpo::positional_options_description pos_options;
  pos_options
    .add("map-file", 1)
    .add("port", 1)
    ;

  bpo::variables_map vm;

  try {
    bpo::store(bpo::command_line_parser(argc,argv)
           .options(options)
           .positional(pos_options)
           .run(),
           vm);
    bpo::notify(vm);

  } catch (std::exception &e) {
    std::cerr << "Unable to parse command line options because: " << e.what() << "\n"
			  << "This is a bug, please report it at " PACKAGE_BUGREPORT << "\n";
    return EXIT_FAILURE;
  }

  if (vm.count("help")) {
    std::cout << options << "\n";
    return EXIT_SUCCESS;
  }

  // argument checking and verification
  for (auto arg : {"map-file", "port"}) {
    if (vm.count(arg) == 0) {
      std::cerr << "The <" << arg << "> argument was not provided, but is mandatory\n\n";
      std::cerr << options << "\n";
      return EXIT_FAILURE;
    }
  }

  if (vm.count("scaling-method")) {
    std::string method_str(vm["scaling-method"].as<std::string>());

    boost::optional<mapnik::scaling_method_e> method =
      mapnik::scaling_method_from_string(method_str);

    if (!method) {
      std::cerr << "The string \"" << method_str << "\" was not recognised as a "
          << "valid scaling method by Mapnik.\n";
      return EXIT_FAILURE;
    }

    srv_opts.scaling_method = *method;

  } else {
    // default option
    srv_opts.scaling_method = mapnik::SCALING_NEAR;
  }

  //start up the server
  try {
    // try to register fonts and input plugins
    mapnik::freetype_engine::register_fonts(fonts_dir);
    mapnik::datasource_cache::instance().register_datasources(input_plugins_dir);

    // start the server running
    http::server3::server server("*", srv_opts);
    server.run();

    // TODO: how to pause this thread?
    while (true) {
      sleep(60);
    }

    server.stop();

  } catch (std::exception& e) {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before><commit_msg>Implement correctly TH2Poly::Integral().<commit_after><|endoftext|>


<commit_before>//
// MessagePack for C++ deserializing routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//
#ifndef MSGPACK_UNPACK_HPP__
#define MSGPACK_UNPACK_HPP__

#include "msgpack/unpack.h"
#include "msgpack/object.hpp"
#include "msgpack/zone.hpp"
#include <memory>
#include <stdexcept>

#ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE
#define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE (32*1024)
#endif

namespace msgpack {

struct unpack_error : public std::runtime_error {
	unpack_error(const std::string& msg) :
		std::runtime_error(msg) { }
};

class unpacked {
public:
	unpacked() { }

	unpacked(object obj, std::auto_ptr<msgpack::zone> z) :
		m_obj(obj), m_zone(z) { }

	object& get()
		{ return m_obj; }

	const object& get() const
		{ return m_obj; }

	std::auto_ptr<msgpack::zone>& zone()
		{ return m_zone; }

	const std::auto_ptr<msgpack::zone>& zone() const
		{ return m_zone; }

private:
	object m_obj;
	std::auto_ptr<msgpack::zone> m_zone;
};

class unpacker : public msgpack_unpacker {
public:
	unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE);
	~unpacker();

public:
	/*! 1. reserve buffer. at least `size' bytes of capacity will be ready */
	void reserve_buffer(size_t size);

	/*! 2. read data to the buffer() up to buffer_capacity() bytes */
	char* buffer();
	size_t buffer_capacity() const;

	/*! 3. specify the number of bytes actually copied */
	void buffer_consumed(size_t size);

	/*! 4. repeat next() until it retunrs false */
	bool next(unpacked* result);

	/*! 5. check if the size of message doesn't exceed assumption. */
	size_t message_size() const;

	// Basic usage of the unpacker is as following:
	//
	// msgpack::unpacker pac;
	// while( /* input is readable */ ) {
	//
	//     // 1.
	//     pac.reserve_buffer(32*1024);
	//
	//     // 2.
	//     size_t bytes = input.readsome(pac.buffer(), pac.buffer_capacity());
	//
	//     // error handling ...
	//
	//     // 3.
	//     pac.buffer_consumed(bytes);
	//
	//     // 4.
	//     msgpack::unpacked result;
	//     while(pac.next(&result)) {
	//         // do some with the object with the zone.
	//         msgpack::object obj = result.get();
	//         std::auto_ptr<msgpack:zone> z = result.zone();
	//         on_message(obj, z);
	//
	//         //// boost::shared_ptr is also usable:
	//         // boost::shared_ptr<msgpack::zone> life(z.release());
	//         // on_message(result.get(), life);
	//     }
	//
	//     // 5.
	//     if(pac.message_size() > 10*1024*1024) {
	//         throw std::runtime_error("message is too large");
	//     }
	// }
	//

	/*! for backward compatibility */
	bool execute();

	/*! for backward compatibility */
	object data();

	/*! for backward compatibility */
	zone* release_zone();

	/*! for backward compatibility */
	void reset_zone();

	/*! for backward compatibility */
	void reset();

public:
	// These functions are usable when non-MessagePack message follows after
	// MessagePack message.
	size_t parsed_size() const;

	/*! get address of the buffer that is not parsed */
	char* nonparsed_buffer();
	size_t nonparsed_size() const;

	/*! skip specified size of non-parsed buffer, leaving the buffer */
	// Note that the `size' argument must be smaller than nonparsed_size()
	void skip_nonparsed_buffer(size_t size);

	/*! remove unparsed buffer from unpacker */
	// Note that reset() leaves non-parsed buffer.
	void remove_nonparsed_buffer();

private:
	typedef msgpack_unpacker base;

private:
	unpacker(const unpacker&);
};

static bool unpack(unpacked* result,
		const char* data, size_t len, size_t* offset = NULL);

// obsolete
typedef enum {
	UNPACK_SUCCESS				=  2,
	UNPACK_EXTRA_BYTES			=  1,
	UNPACK_CONTINUE				=  0,
	UNPACK_PARSE_ERROR			= -1,
} unpack_return;

// obsolete
static unpack_return unpack(const char* data, size_t len, size_t* off,
		zone* z, object* result);

// obsolete
static object unpack(const char* data, size_t len, zone& z, size_t* off = NULL);

inline unpacker::unpacker(size_t initial_buffer_size)
{
	if(!msgpack_unpacker_init(this, initial_buffer_size)) {
		throw std::bad_alloc();
	}
}

inline unpacker::~unpacker()
{
	msgpack_unpacker_destroy(this);
}

inline void unpacker::reserve_buffer(size_t size)
{
	if(!msgpack_unpacker_reserve_buffer(this, size)) {
		throw std::bad_alloc();
	}
}

inline char* unpacker::buffer()
{
	return msgpack_unpacker_buffer(this);
}

inline size_t unpacker::buffer_capacity() const
{
	return msgpack_unpacker_buffer_capacity(this);
}

inline void unpacker::buffer_consumed(size_t size)
{
	return msgpack_unpacker_buffer_consumed(this, size);
}

inline bool unpacker::next(unpacked* result)
{
	int ret = msgpack_unpacker_execute(this);
	if(ret < 0) {
		throw unpack_error("parse error");
	}

	result->zone().reset( release_zone() );
	result->get() = data();
	reset();

	return ret > 0;
}

inline bool unpacker::execute()
{
	int ret = msgpack_unpacker_execute(this);
	if(ret < 0) {
		throw unpack_error("parse error");
	} else if(ret == 0) {
		return false;
	} else {
		return true;
	}
}

inline object unpacker::data()
{
	return msgpack_unpacker_data(this);
}

inline zone* unpacker::release_zone()
{
	if(!msgpack_unpacker_flush_zone(this)) {
		throw std::bad_alloc();
	}

	zone* r = new zone();

	msgpack_zone old = *base::z;
	*base::z = *r;
	*static_cast<msgpack_zone*>(r) = old;

	return r;
}

inline void unpacker::reset_zone()
{
	msgpack_unpacker_reset_zone(this);
}

inline void unpacker::reset()
{
	msgpack_unpacker_reset(this);
}

inline size_t unpacker::message_size() const
{
	return msgpack_unpacker_message_size(this);
}

inline size_t unpacker::parsed_size() const
{
	return msgpack_unpacker_parsed_size(this);
}

inline char* unpacker::nonparsed_buffer()
{
	return base::buffer + base::off;
}

inline size_t unpacker::nonparsed_size() const
{
	return base::used - base::off;
}

inline void unpacker::skip_nonparsed_buffer(size_t size)
{
	base::off += size;
}

inline void unpacker::remove_nonparsed_buffer()
{
	base::used = base::off;
}

inline bool unpack(unpacked* result,
		const char* data, size_t len, size_t* offset)
{
	msgpack::object obj;
	std::auto_ptr<msgpack::zone> z(new zone());

	unpack_return ret = (unpack_return)msgpack_unpack(
			data, len, offset, z.get(),
			reinterpret_cast<msgpack_object*>(&obj));

	switch(ret) {
	case UNPACK_SUCCESS:
		result->get() = obj;
		result->zone() = z;
		return false;

	case UNPACK_EXTRA_BYTES:
		result->get() = obj;
		result->zone() = z;
		return true;

	case UNPACK_CONTINUE:
		throw unpack_error("insufficient bytes");

	case UNPACK_PARSE_ERROR:
	default:
		throw unpack_error("parse error");
	}
}

// obsolete
inline unpack_return unpack(const char* data, size_t len, size_t* off,
		zone* z, object* result)
{
	return (unpack_return)msgpack_unpack(data, len, off,
			z, reinterpret_cast<msgpack_object*>(result));
}

// obsolete
inline object unpack(const char* data, size_t len, zone& z, size_t* off)
{
	object result;

	switch( msgpack::unpack(data, len, off, &z, &result) ) {
	case UNPACK_SUCCESS:
		return result;

	case UNPACK_EXTRA_BYTES:
		if(off) {
			return result;
		} else {
			throw unpack_error("extra bytes");
		}

	case UNPACK_CONTINUE:
		throw unpack_error("insufficient bytes");

	case UNPACK_PARSE_ERROR:
	default:
		throw unpack_error("parse error");
	}
}

}  // namespace msgpack

#endif /* msgpack/unpack.hpp */

<commit_msg>cpp: fixes unpacker::next<commit_after>//
// MessagePack for C++ deserializing routine
//
// Copyright (C) 2008-2009 FURUHASHI Sadayuki
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
//
#ifndef MSGPACK_UNPACK_HPP__
#define MSGPACK_UNPACK_HPP__

#include "msgpack/unpack.h"
#include "msgpack/object.hpp"
#include "msgpack/zone.hpp"
#include <memory>
#include <stdexcept>

#ifndef MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE
#define MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE (32*1024)
#endif

namespace msgpack {

struct unpack_error : public std::runtime_error {
	unpack_error(const std::string& msg) :
		std::runtime_error(msg) { }
};

class unpacked {
public:
	unpacked() { }

	unpacked(object obj, std::auto_ptr<msgpack::zone> z) :
		m_obj(obj), m_zone(z) { }

	object& get()
		{ return m_obj; }

	const object& get() const
		{ return m_obj; }

	std::auto_ptr<msgpack::zone>& zone()
		{ return m_zone; }

	const std::auto_ptr<msgpack::zone>& zone() const
		{ return m_zone; }

private:
	object m_obj;
	std::auto_ptr<msgpack::zone> m_zone;
};

class unpacker : public msgpack_unpacker {
public:
	unpacker(size_t init_buffer_size = MSGPACK_UNPACKER_DEFAULT_INITIAL_BUFFER_SIZE);
	~unpacker();

public:
	/*! 1. reserve buffer. at least `size' bytes of capacity will be ready */
	void reserve_buffer(size_t size);

	/*! 2. read data to the buffer() up to buffer_capacity() bytes */
	char* buffer();
	size_t buffer_capacity() const;

	/*! 3. specify the number of bytes actually copied */
	void buffer_consumed(size_t size);

	/*! 4. repeat next() until it retunrs false */
	bool next(unpacked* result);

	/*! 5. check if the size of message doesn't exceed assumption. */
	size_t message_size() const;

	// Basic usage of the unpacker is as following:
	//
	// msgpack::unpacker pac;
	// while( /* input is readable */ ) {
	//
	//     // 1.
	//     pac.reserve_buffer(32*1024);
	//
	//     // 2.
	//     size_t bytes = input.readsome(pac.buffer(), pac.buffer_capacity());
	//
	//     // error handling ...
	//
	//     // 3.
	//     pac.buffer_consumed(bytes);
	//
	//     // 4.
	//     msgpack::unpacked result;
	//     while(pac.next(&result)) {
	//         // do some with the object with the zone.
	//         msgpack::object obj = result.get();
	//         std::auto_ptr<msgpack:zone> z = result.zone();
	//         on_message(obj, z);
	//
	//         //// boost::shared_ptr is also usable:
	//         // boost::shared_ptr<msgpack::zone> life(z.release());
	//         // on_message(result.get(), life);
	//     }
	//
	//     // 5.
	//     if(pac.message_size() > 10*1024*1024) {
	//         throw std::runtime_error("message is too large");
	//     }
	// }
	//

	/*! for backward compatibility */
	bool execute();

	/*! for backward compatibility */
	object data();

	/*! for backward compatibility */
	zone* release_zone();

	/*! for backward compatibility */
	void reset_zone();

	/*! for backward compatibility */
	void reset();

public:
	// These functions are usable when non-MessagePack message follows after
	// MessagePack message.
	size_t parsed_size() const;

	/*! get address of the buffer that is not parsed */
	char* nonparsed_buffer();
	size_t nonparsed_size() const;

	/*! skip specified size of non-parsed buffer, leaving the buffer */
	// Note that the `size' argument must be smaller than nonparsed_size()
	void skip_nonparsed_buffer(size_t size);

	/*! remove unparsed buffer from unpacker */
	// Note that reset() leaves non-parsed buffer.
	void remove_nonparsed_buffer();

private:
	typedef msgpack_unpacker base;

private:
	unpacker(const unpacker&);
};

static bool unpack(unpacked* result,
		const char* data, size_t len, size_t* offset = NULL);

// obsolete
typedef enum {
	UNPACK_SUCCESS				=  2,
	UNPACK_EXTRA_BYTES			=  1,
	UNPACK_CONTINUE				=  0,
	UNPACK_PARSE_ERROR			= -1,
} unpack_return;

// obsolete
static unpack_return unpack(const char* data, size_t len, size_t* off,
		zone* z, object* result);

// obsolete
static object unpack(const char* data, size_t len, zone& z, size_t* off = NULL);

inline unpacker::unpacker(size_t initial_buffer_size)
{
	if(!msgpack_unpacker_init(this, initial_buffer_size)) {
		throw std::bad_alloc();
	}
}

inline unpacker::~unpacker()
{
	msgpack_unpacker_destroy(this);
}

inline void unpacker::reserve_buffer(size_t size)
{
	if(!msgpack_unpacker_reserve_buffer(this, size)) {
		throw std::bad_alloc();
	}
}

inline char* unpacker::buffer()
{
	return msgpack_unpacker_buffer(this);
}

inline size_t unpacker::buffer_capacity() const
{
	return msgpack_unpacker_buffer_capacity(this);
}

inline void unpacker::buffer_consumed(size_t size)
{
	return msgpack_unpacker_buffer_consumed(this, size);
}

inline bool unpacker::next(unpacked* result)
{
	int ret = msgpack_unpacker_execute(this);

	if(ret < 0) {
		throw unpack_error("parse error");
	}

	if(ret == 0) {
		result->zone().reset();
		result->get() = object();
		return false;

	} else {
		result->zone().reset( release_zone() );
		result->get() = data();
		reset();
		return true;
	}
}

inline bool unpacker::execute()
{
	int ret = msgpack_unpacker_execute(this);
	if(ret < 0) {
		throw unpack_error("parse error");
	} else if(ret == 0) {
		return false;
	} else {
		return true;
	}
}

inline object unpacker::data()
{
	return msgpack_unpacker_data(this);
}

inline zone* unpacker::release_zone()
{
	if(!msgpack_unpacker_flush_zone(this)) {
		throw std::bad_alloc();
	}

	zone* r = new zone();

	msgpack_zone old = *base::z;
	*base::z = *r;
	*static_cast<msgpack_zone*>(r) = old;

	return r;
}

inline void unpacker::reset_zone()
{
	msgpack_unpacker_reset_zone(this);
}

inline void unpacker::reset()
{
	msgpack_unpacker_reset(this);
}

inline size_t unpacker::message_size() const
{
	return msgpack_unpacker_message_size(this);
}

inline size_t unpacker::parsed_size() const
{
	return msgpack_unpacker_parsed_size(this);
}

inline char* unpacker::nonparsed_buffer()
{
	return base::buffer + base::off;
}

inline size_t unpacker::nonparsed_size() const
{
	return base::used - base::off;
}

inline void unpacker::skip_nonparsed_buffer(size_t size)
{
	base::off += size;
}

inline void unpacker::remove_nonparsed_buffer()
{
	base::used = base::off;
}

inline bool unpack(unpacked* result,
		const char* data, size_t len, size_t* offset)
{
	msgpack::object obj;
	std::auto_ptr<msgpack::zone> z(new zone());

	unpack_return ret = (unpack_return)msgpack_unpack(
			data, len, offset, z.get(),
			reinterpret_cast<msgpack_object*>(&obj));

	switch(ret) {
	case UNPACK_SUCCESS:
		result->get() = obj;
		result->zone() = z;
		return false;

	case UNPACK_EXTRA_BYTES:
		result->get() = obj;
		result->zone() = z;
		return true;

	case UNPACK_CONTINUE:
		throw unpack_error("insufficient bytes");

	case UNPACK_PARSE_ERROR:
	default:
		throw unpack_error("parse error");
	}
}

// obsolete
inline unpack_return unpack(const char* data, size_t len, size_t* off,
		zone* z, object* result)
{
	return (unpack_return)msgpack_unpack(data, len, off,
			z, reinterpret_cast<msgpack_object*>(result));
}

// obsolete
inline object unpack(const char* data, size_t len, zone& z, size_t* off)
{
	object result;

	switch( msgpack::unpack(data, len, off, &z, &result) ) {
	case UNPACK_SUCCESS:
		return result;

	case UNPACK_EXTRA_BYTES:
		if(off) {
			return result;
		} else {
			throw unpack_error("extra bytes");
		}

	case UNPACK_CONTINUE:
		throw unpack_error("insufficient bytes");

	case UNPACK_PARSE_ERROR:
	default:
		throw unpack_error("parse error");
	}
}

}  // namespace msgpack

#endif /* msgpack/unpack.hpp */

<|endoftext|>


<commit_before>#include "RenderSystem.h"
#include "ECS.h"
#include "../Components/Sprite.h"
#include "../Components/Transform.h"
#include <SDL2/SDL_render.h>

#include "../Components/Animation.h"
#include "../Components/SpriteSheet.h"
#include "../Components/Kinematic.h"
#include "../Utility/TextureLoader.h"

RenderSystem::RenderSystem()
{
	ecs = nullptr;
	transformManager = nullptr;
	spriteManager = nullptr;
}

RenderSystem::RenderSystem(ECS* ecs)
{
	this->ecs = ecs;
	transformManager = &(ecs->transforms);
	spriteManager = &(ecs->sprites);
}

RenderSystem::~RenderSystem()
{
}

void RenderSystem::Init(int cameraWidth,int cameraHeight)
{
	camera.x = 0;
	camera.y = 0;
	camera.w = cameraWidth;
	camera.h = cameraHeight;

	//int playerID = ecs->entitySystem.GetIDs("Player").at(0);
	//SetEntityToFollow(playerID);
}

void RenderSystem::SetLocation(int x, int y)
{
	camera.x = x;
	camera.y = y;
}

//temporary level dimensions
#define LEVEL_WIDTH 800
#define LEVEL_HEIGHT 600
//#define LEVEL_WIDTH 2048
//#define LEVEL_HEIGHT 1840
bool RenderSystem::SetEntityToFollow(int id)
{
	//target entity's components
	Transform* transformComponent = transformManager->GetComponent(id);
	Sprite* spriteComponent = spriteManager->GetComponent(id);
	if (transformComponent != nullptr && spriteComponent != nullptr)
	{
		SDL_Point targetPos = getFloatToIntegerCoordinates(transformComponent->position);

		//set a camera offset relative to the entity ~ camera centered on target entity
		camera.x = (targetPos.x + spriteComponent->width / 2) - (camera.w / 2);
		camera.y = (targetPos.y + spriteComponent->height / 2) - (camera.h / 2);

		//have camera not move for now
		//camera.x = 0;
		//camera.y = 0;

		//camera bounds check relative to world coordinates
		if (camera.x < 0)
			camera.x = 0;
		if (camera.y < 0)
			camera.y = 0;
		if (camera.x + camera.w > LEVEL_WIDTH)
			camera.x = LEVEL_WIDTH - camera.w;
		if (camera.y + camera.h > LEVEL_HEIGHT)
			camera.y = LEVEL_HEIGHT - camera.h;
	}

	return transformComponent != nullptr && spriteComponent != nullptr;

}

//I could pass SDL_Renderer* here instead and would not need to include
//a SDL_Renderer* pointer as a data member...
void RenderSystem::Update(SDL_Renderer* render)
{

	//camera tracking
	int backgroundID = ecs->entitySystem.GetIDs("Background").at(0);

	//int playerID = ecs->entitySystem.GetIDs("Player").at(0);
	//SetEntityToFollow(playerID);

	vector<int> ids = ecs->entitySystem.GetIDs();
	for (auto it = ids.begin();it != ids.end();++it)
	{
		Transform* transform = transformManager->GetComponent(*it);
		Sprite* sprite = spriteManager->GetComponent(*it);

		if (transform != nullptr && sprite != nullptr)
		{

			sprite->position = getFloatToIntegerCoordinates(transform->position);

			//temp code ~ needs to be refactored...
			if (backgroundID == *it)
			{
	/*			SDL_Rect bounds;
				bounds.h = camera.h;
				bounds.w = camera.w;*/
				//always render the background since all of its parts will always be seen in the game.
				SDL_RenderCopy(render, sprite->texture, &camera, NULL);
			}
			//else if (playerID == *it)
			//{

			//	//this effect makes it as if the camera is following the player.
			//	//but in reality this is making sure the player stays withing bounds of the camera.
			//	//convert player world coordinates to screen coordinates relative to camera
			//	SDL_Rect screenBounds;
			//	screenBounds.x = sprite->position.x - camera.x;
			//	screenBounds.y = sprite->position.y - camera.y;
			//	screenBounds.w = sprite->width;
			//	screenBounds.h = sprite->height;
			//	//SDL_RenderCopy(render, sprite->texture, NULL/* source texture is used if I want to animate the sprite*/, &screenBounds);
			//}
			else //for all other sprites... render them  (right now render order happens from lowest entity id to highest entity id)
			{
				//render the sprite if it is seen by the camera (check if sprite is within screen bounds)
				SDL_Rect screenCoords;
				screenCoords.x = sprite->position.x - camera.x;
				screenCoords.y = sprite->position.y - camera.y;
				//width and height of the sprite
				screenCoords.w = sprite->width;
				screenCoords.h = sprite->height;

				//reminder: all rectangle based textures locations are measured on the top left corner.
				/* o is the top left corner of the rectangle, the 3 other corners aren't calculated.
					o---------------x
					|				|
					|				|
					|				|
					x---------------x
				*/

				//this is an optimization for rendering since rendering many textures offscreen each frame is expensive
				if (screenCoords.x >= 0 && screenCoords.x < camera.w
					&& screenCoords.y >= 0 && screenCoords.y < camera.h)
				{
					//render the sprite if it is within camera bounds
					SDL_RenderCopy(render, sprite->texture, NULL, &screenCoords);
				}
				else
				{
					//only render tiles where there right corners can be caught within camera bounds.
					SDL_Point rightCorner;//bottom right corner
					rightCorner.x = screenCoords.x + screenCoords.w;
					rightCorner.y = screenCoords.y + screenCoords.h;
					if (rightCorner.x >= 0 && rightCorner.x < camera.w)
					{
						SDL_RenderCopy(render, sprite->texture, NULL, &screenCoords);
					}
					else if (rightCorner.y >= 0 && rightCorner.y < camera.h)
					{
						SDL_RenderCopy(render, sprite->texture, NULL, &screenCoords);
					}
				}

			}
		}
	}

	//temp code
	//auto playerTransform = ecs->transforms.GetComponent(playerID);
	//auto playerKinematic = ecs->kinematics.GetComponent(playerID);
	//auto playerAnimation = ecs->animations.GetComponent(playerID);
	//if (playerTransform == nullptr || playerKinematic == nullptr || playerAnimation == nullptr)
	//	return;

	//SpriteSheet* currentAnim = playerAnimation->Get("idle");
	//SDL_Rect srcRect = currentAnim->PlayAnimation(0.166f, 0.5f);
	//SDL_RendererFlip flip = SDL_FLIP_NONE;

	//if (playerKinematic->velocity.x != 0.0f && playerKinematic->velocity.y == 0.0f)
	//{
	//	currentAnim = playerAnimation->Get("walk");
	//	if (playerKinematic->velocity.x < 0.0f)
	//		flip = SDL_FLIP_HORIZONTAL;
	//	else
	//		flip = SDL_FLIP_NONE;
	//	srcRect = currentAnim->PlayAnimation(0.166f, 0.5f);
	//}
	//if (playerKinematic->velocity.y != 0.0f)
	//{
	//	currentAnim = playerAnimation->Get("jump");
	//	if (playerKinematic->velocity.x < 0.0f)
	//		flip = SDL_FLIP_HORIZONTAL;
	//	else
	//		flip = SDL_FLIP_NONE;
	//	srcRect = currentAnim->PlayAnimation(0.166f, 2.5f);
	//}

	////convert game coordinates to screen coordinates
	////move this to sprite component and spritesheet component
	//SDL_Point tempoffset{ 20, 1 };
	//currentAnim->offset = tempoffset;
	//currentAnim->position = getFloatToIntegerCoordinates(playerTransform->position);
	//SDL_Rect screenBounds;
	//screenBounds.x = currentAnim->GetPosition().x - camera.x;
	//screenBounds.y = currentAnim->GetPosition().y - camera.y;
	//screenBounds.w = 32 * 2;
	//screenBounds.h = 64 * 2;
	//SDL_RenderCopyEx(render, currentAnim->image->texture, &srcRect, &screenBounds, 0.0f, NULL, flip);
}

void RenderSystem::Draw(SDL_Renderer* render)
{
	SDL_RenderPresent(render);
	SDL_RenderClear(render);
}

//probably pull out as a utility function
SDL_Point RenderSystem::getFloatToIntegerCoordinates(Vect2 position)
{
	return SDL_Point{ (int)roundf(position.x), (int)roundf(position.y) };
}

<commit_msg>Minor changes to allow swift changes between AnimationTest.cpp and TileMapTest cpp file<commit_after>#include "RenderSystem.h"
#include "ECS.h"
#include "../Components/Sprite.h"
#include "../Components/Transform.h"
#include <SDL2/SDL_render.h>

#include "../Components/Animation.h"
#include "../Components/SpriteSheet.h"
#include "../Components/Kinematic.h"
#include "../Utility/TextureLoader.h"

RenderSystem::RenderSystem()
{
	ecs = nullptr;
	transformManager = nullptr;
	spriteManager = nullptr;
}

RenderSystem::RenderSystem(ECS* ecs)
{
	this->ecs = ecs;
	transformManager = &(ecs->transforms);
	spriteManager = &(ecs->sprites);
}

RenderSystem::~RenderSystem()
{
}

void RenderSystem::Init(int cameraWidth,int cameraHeight)
{
	camera.x = 0;
	camera.y = 0;
	camera.w = cameraWidth;
	camera.h = cameraHeight;

	if (ecs->entitySystem.ContainsEntityType("Player"))
	{
		int playerID = ecs->entitySystem.GetIDs("Player").at(0);
		SetEntityToFollow(playerID);
	}
}

void RenderSystem::SetLocation(int x, int y)
{
	camera.x = x;
	camera.y = y;
}

//temporary level dimensions
//#define LEVEL_WIDTH 800
//#define LEVEL_HEIGHT 600
#define LEVEL_WIDTH 2048
#define LEVEL_HEIGHT 1840
bool RenderSystem::SetEntityToFollow(int id)
{
	//target entity's components
	Transform* transformComponent = transformManager->GetComponent(id);
	Sprite* spriteComponent = spriteManager->GetComponent(id);
	if (transformComponent != nullptr && spriteComponent != nullptr)
	{
		SDL_Point targetPos = getFloatToIntegerCoordinates(transformComponent->position);

		//set a camera offset relative to the entity ~ camera centered on target entity
		camera.x = (targetPos.x + spriteComponent->width / 2) - (camera.w / 2);
		camera.y = (targetPos.y + spriteComponent->height / 2) - (camera.h / 2);

		//have camera not move for now
		//camera.x = 0;
		//camera.y = 0;

		//camera bounds check relative to world coordinates
		if (camera.x < 0)
			camera.x = 0;
		if (camera.y < 0)
			camera.y = 0;
		if (camera.x + camera.w > LEVEL_WIDTH)
			camera.x = LEVEL_WIDTH - camera.w;
		if (camera.y + camera.h > LEVEL_HEIGHT)
			camera.y = LEVEL_HEIGHT - camera.h;
	}

	return transformComponent != nullptr && spriteComponent != nullptr;

}

//I could pass SDL_Renderer* here instead and would not need to include
//a SDL_Renderer* pointer as a data member...
void RenderSystem::Update(SDL_Renderer* render)
{

	//camera tracking
	int backgroundID = ecs->entitySystem.GetIDs("Background").at(0);

	//ids will never be < 0
	int playerID = -1;
	if (ecs->entitySystem.ContainsEntityType("Player"))
	{
		playerID = ecs->entitySystem.GetIDs("Player").at(0);
		SetEntityToFollow(playerID);
	}

	vector<int> ids = ecs->entitySystem.GetIDs();
	for (auto it = ids.begin();it != ids.end();++it)
	{
		Transform* transform = transformManager->GetComponent(*it);
		Sprite* sprite = spriteManager->GetComponent(*it);

		if (transform != nullptr && sprite != nullptr)
		{

			sprite->position = getFloatToIntegerCoordinates(transform->position);

			//temp code ~ needs to be refactored...
			if (backgroundID == *it)
			{
				//always render the background since all of its parts will always be seen in the game.
				SDL_RenderCopy(render, sprite->texture, &camera, NULL);
			}
			else if (playerID == *it)
			{
				//this effect makes it as if the camera is following the player.
				//but in reality this is making sure the player stays withing bounds of the camera.
				//convert player world coordinates to screen coordinates relative to camera
				SDL_Rect screenBounds;
				screenBounds.x = sprite->position.x - camera.x;
				screenBounds.y = sprite->position.y - camera.y;
				screenBounds.w = sprite->width;
				screenBounds.h = sprite->height;
				SDL_RenderCopy(render, sprite->texture, NULL/* source texture is used if I want to animate the sprite*/, &screenBounds);
			}
			else //for all other sprites... render them  (right now render order happens from lowest entity id to highest entity id)
			{
				//render the sprite if it is seen by the camera (check if sprite is within screen bounds)
				SDL_Rect screenCoords;
				screenCoords.x = sprite->position.x - camera.x;
				screenCoords.y = sprite->position.y - camera.y;
				//width and height of the sprite
				screenCoords.w = sprite->width;
				screenCoords.h = sprite->height;

				//reminder: all rectangle based textures locations are measured on the top left corner.
				/* o is the top left corner of the rectangle, the 3 other corners aren't calculated.
					o---------------x
					|				|
					|				|
					|				|
					x---------------x
				*/

				//this is an optimization for rendering since rendering many textures offscreen each frame is expensive
				if (screenCoords.x >= 0 && screenCoords.x < camera.w
					&& screenCoords.y >= 0 && screenCoords.y < camera.h)
				{
					//render the sprite if it is within camera bounds
					SDL_RenderCopy(render, sprite->texture, NULL, &screenCoords);
				}
				else
				{
					//only render tiles where there right corners can be caught within camera bounds.
					SDL_Point rightCorner;//bottom right corner
					rightCorner.x = screenCoords.x + screenCoords.w;
					rightCorner.y = screenCoords.y + screenCoords.h;
					if (rightCorner.x >= 0 && rightCorner.x < camera.w)
					{
						SDL_RenderCopy(render, sprite->texture, NULL, &screenCoords);
					}
					else if (rightCorner.y >= 0 && rightCorner.y < camera.h)
					{
						SDL_RenderCopy(render, sprite->texture, NULL, &screenCoords);
					}
				}

			}
		}
	}

	//temp code
	if (playerID != -1)
	{
		auto playerTransform = ecs->transforms.GetComponent(playerID);
		auto playerKinematic = ecs->kinematics.GetComponent(playerID);
		auto playerAnimation = ecs->animations.GetComponent(playerID);
		if (playerTransform == nullptr || playerKinematic == nullptr || playerAnimation == nullptr)
			return;

		SpriteSheet* currentAnim = playerAnimation->Get("idle");
		SDL_Rect srcRect = currentAnim->PlayAnimation(0.166f, 0.5f);
		SDL_RendererFlip flip = SDL_FLIP_NONE;

		if (playerKinematic->velocity.x != 0.0f && playerKinematic->velocity.y == 0.0f)
		{
			currentAnim = playerAnimation->Get("walk");
			if (playerKinematic->velocity.x < 0.0f)
				flip = SDL_FLIP_HORIZONTAL;
			else
				flip = SDL_FLIP_NONE;
			srcRect = currentAnim->PlayAnimation(0.166f, 0.5f);
		}
		if (playerKinematic->velocity.y != 0.0f)
		{
			currentAnim = playerAnimation->Get("jump");
			if (playerKinematic->velocity.x < 0.0f)
				flip = SDL_FLIP_HORIZONTAL;
			else
				flip = SDL_FLIP_NONE;
			srcRect = currentAnim->PlayAnimation(0.166f, 2.5f);
		}

		//convert game coordinates to screen coordinates
		//move this to sprite component and spritesheet component
		SDL_Point tempoffset{ 20, 1 };
		currentAnim->offset = tempoffset;
		currentAnim->position = getFloatToIntegerCoordinates(playerTransform->position);
		SDL_Rect screenBounds;
		screenBounds.x = currentAnim->GetPosition().x - camera.x;
		screenBounds.y = currentAnim->GetPosition().y - camera.y;
		screenBounds.w = 32 * 2;
		screenBounds.h = 64 * 2;
		SDL_RenderCopyEx(render, currentAnim->image->texture, &srcRect, &screenBounds, 0.0f, NULL, flip);
	}
}

void RenderSystem::Draw(SDL_Renderer* render)
{
	SDL_RenderPresent(render);
	SDL_RenderClear(render);
}

//probably pull out as a utility function
SDL_Point RenderSystem::getFloatToIntegerCoordinates(Vect2 position)
{
	return SDL_Point{ (int)roundf(position.x), (int)roundf(position.y) };
}

<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
 * Copyright 2015 Cloudius Systems
 *
 * Modified by Cloudius Systems
 */

#pragma once

#include "operation.hh"
#include "constants.hh"

namespace cql3 {

class operation::set_value : public raw_update {
private:
    ::shared_ptr<term::raw> _value;
public:
    set_value(::shared_ptr<term::raw> value) : _value(std::move(value)) {}

    virtual ::shared_ptr <operation> prepare(const sstring& keyspace, column_definition& receiver) override {
        auto v = _value->prepare(keyspace, receiver.column_specification);

        if (receiver.type->is_counter()) {
            throw exceptions::invalid_request_exception(sprint("Cannot set the value of counter column %s (counters can only be incremented/decremented, not set)", receiver.name_as_text()));
        }

        if (!receiver.type->is_collection()) {
            return ::make_shared<constants::setter>(receiver, v);
        }

        throw std::runtime_error("not implemented"); // FIXME
#if 0
            switch (((CollectionType)receiver.type).kind)
            {
                case LIST:
                    return new Lists.Setter(receiver, v);
                case SET:
                    return new Sets.Setter(receiver, v);
                case MAP:
                    return new Maps.Setter(receiver, v);
            }
            throw new AssertionError();
#endif
    }

#if 0
        protected String toString(ColumnSpecification column)
        {
            return String.format("%s = %s", column, value);
        }
#endif

    virtual bool is_compatible_with(::shared_ptr <raw_update> other) override {
        // We don't allow setting multiple time the same column, because 1)
        // it's stupid and 2) the result would seem random to the user.
        return false;
    }
};

}
<commit_msg>cql3: implement operation::setter::prepare() for maps<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
 * Copyright 2015 Cloudius Systems
 *
 * Modified by Cloudius Systems
 */

#pragma once

#include "operation.hh"
#include "constants.hh"
#include "maps.hh"

namespace cql3 {

class operation::set_value : public raw_update {
private:
    ::shared_ptr<term::raw> _value;
public:
    set_value(::shared_ptr<term::raw> value) : _value(std::move(value)) {}

    virtual ::shared_ptr <operation> prepare(const sstring& keyspace, column_definition& receiver) override {
        auto v = _value->prepare(keyspace, receiver.column_specification);

        if (receiver.type->is_counter()) {
            throw exceptions::invalid_request_exception(sprint("Cannot set the value of counter column %s (counters can only be incremented/decremented, not set)", receiver.name_as_text()));
        }

        if (!receiver.type->is_collection()) {
            return ::make_shared<constants::setter>(receiver, v);
        }

        auto& k = static_pointer_cast<collection_type_impl>(receiver.type)->_kind;
        if (&k == &collection_type_impl::kind::list) {
            throw std::runtime_error("not implemented"); // FIXME
            // return new Lists.Setter(receiver, v);
        } else if (&k == &collection_type_impl::kind::set) {
            throw std::runtime_error("not implemented"); // FIXME
            // return new Sets.Setter(receiver, v);
        } else if (&k == &collection_type_impl::kind::map) {
            return make_shared<maps::setter>(receiver, v);
        } else {
            abort();
        }
    }

#if 0
        protected String toString(ColumnSpecification column)
        {
            return String.format("%s = %s", column, value);
        }
#endif

    virtual bool is_compatible_with(::shared_ptr <raw_update> other) override {
        // We don't allow setting multiple time the same column, because 1)
        // it's stupid and 2) the result would seem random to the user.
        return false;
    }
};

}
<|endoftext|>


<commit_before>// AliEmcalCorrectionCellTimeCalib
//

#include <TObjArray.h>
#include <TFile.h>
#include "AliEMCALGeometry.h"
#include "AliOADBContainer.h"
#include "AliEMCALRecoUtils.h"
#include "AliAODEvent.h"

#include "AliEmcalCorrectionCellTimeCalib.h"

/// \cond CLASSIMP
ClassImp(AliEmcalCorrectionCellTimeCalib);
/// \endcond

// Actually registers the class with the base class
RegisterCorrectionComponent<AliEmcalCorrectionCellTimeCalib> AliEmcalCorrectionCellTimeCalib::reg("AliEmcalCorrectionCellTimeCalib");

/**
 * Default constructor
 */
AliEmcalCorrectionCellTimeCalib::AliEmcalCorrectionCellTimeCalib() :
  AliEmcalCorrectionComponent("AliEmcalCorrectionCellTimeCalib")
  ,fCalibrateTime(kFALSE)
  ,fCalibrateTimeL1Phase(kFALSE)
  ,fUseAutomaticTimeCalib(1)
  ,fCellTimeDistBefore(0)
  ,fCellTimeDistAfter(0)
{
}

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

/**
 * Initialize and configure the component.
 */
Bool_t AliEmcalCorrectionCellTimeCalib::Initialize()
{
  // Initialization
  AliEmcalCorrectionComponent::Initialize();

  AliWarning("Init EMCAL time calibration");

  GetProperty("createHistos", fCreateHisto);

  fCalibrateTime = kTRUE;

  // init reco utils
  if (!fRecoUtils)
    fRecoUtils  = new AliEMCALRecoUtils;

  fRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal);

  return kTRUE;
}

/**
 * Create run-independent objects for output. Called before running over events.
 */
void AliEmcalCorrectionCellTimeCalib::UserCreateOutputObjects()
{
  AliEmcalCorrectionComponent::UserCreateOutputObjects();

  if (fCreateHisto){
    fCellTimeDistBefore = new TH1F("hCellTimeDistBefore","hCellTimeDistBefore;t_cell",1000,-10e-6,10e-6);
    fOutput->Add(fCellTimeDistBefore);
    fCellTimeDistAfter = new TH1F("hCellTimeDistAfter","hCellTimeDistAfter;t_cell",1000,-10e-6,10e-6);
    fOutput->Add(fCellTimeDistAfter);
  }
}

/**
 * Called for each event to process the event data.
 */
Bool_t AliEmcalCorrectionCellTimeCalib::Run()
{
  AliEmcalCorrectionComponent::Run();

  if (!fEvent) {
    AliError("Event ptr = 0, returning");
    return kFALSE;
  }

  CheckIfRunChanged();

  // CONFIGURE THE RECO UTILS -------------------------------------------------

  // allows time calibration
  if (fCalibrateTime)
    fRecoUtils->SwitchOnTimeRecalibration();
  else
    fRecoUtils->SwitchOffTimeRecalibration();

  // allows time calibration with L1 phase
  if (fCalibrateTimeL1Phase)
    fRecoUtils->SwitchOnL1PhaseInTimeRecalibration();
  else
    fRecoUtils->SwitchOffL1PhaseInTimeRecalibration();

  // START PROCESSING ---------------------------------------------------------
  // Test if cells present
  if (fCaloCells->GetNumberOfCells()<=0)
  {
    AliWarning(Form("Number of EMCAL cells = %d, returning", fCaloCells->GetNumberOfCells()));
    return kFALSE;
  }

  // mark the cells not recalibrated
  fRecoUtils->ResetCellsCalibrated();

  if(fCreateHisto)
    FillCellQA(fCellTimeDistBefore); // "before" QA

  // CELL RECALIBRATION -------------------------------------------------------
  // cell objects will be updated
  UpdateCells();

  if(fCreateHisto)
    FillCellQA(fCellTimeDistAfter); // "after" QA

  return kTRUE;
}

/**
 * Initialize the time calibration.
 */
Int_t AliEmcalCorrectionCellTimeCalib::InitTimeCalibration()
{
  // Initialising bad channel maps

  if (!fEvent)
    return 0;

  AliInfo("Initialising time calibration map");

  // init default maps first
  if (!fRecoUtils->GetEMCALTimeRecalibrationFactorsArray())
    fRecoUtils->InitEMCALTimeRecalibrationFactors() ;

  Int_t runBC = fEvent->GetRunNumber();

  AliOADBContainer *contBC = new AliOADBContainer("");
  if (fBasePath!="")
  { //if fBasePath specified in the ->SetBasePath()
    AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));

    TFile *fbad=new TFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"read");
    if (!fbad || fbad->IsZombie())
    {
      AliFatal(Form("EMCALTimeCalib.root was not found in the path provided: %s",fBasePath.Data()));
      return 0;
    }

    if (fbad) delete fbad;

    contBC->InitFromFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"AliEMCALTimeCalib");
  }
  else
  { // Else choose the one in the $ALICE_PHYSICS directory
    AliInfo("Loading time calibration OADB from $ALICE_PHYSICS/OADB/EMCAL");

    TFile *fbad=new TFile("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeCalib.root","read");
    if (!fbad || fbad->IsZombie())
    {
      AliFatal("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeCalib.root was not found");
      return 0;
    }

    if (fbad) delete fbad;

    contBC->InitFromFile("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeCalib.root","AliEMCALTimeCalib");
  }

  TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
  if (!arrayBC)
  {
    AliError(Form("No external time calibration set for run number: %d", runBC));
    delete contBC;
    return 2;
  }

  // Here, it looks for a specific pass
  TString pass = fFilepass;
  if (fFilepass=="calo_spc") pass ="pass1";
  TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(pass);
  if (!arrayBCpass)
  {
    AliError(Form("No external time calibration set for: %d -%s", runBC,pass.Data()));
    delete contBC;
    return 2;
  }

  arrayBCpass->Print();

  for(Int_t i = 0; i < 4; i++)
  {
    TH1F *h = fRecoUtils->GetEMCALChannelTimeRecalibrationFactors(i);
    if (h)
      delete h;

    h = (TH1F*)arrayBCpass->FindObject(Form("hAllTimeAvBC%d",i));

    if (!h)
    {
      AliError(Form("Can not get hAllTimeAvBC%d",i));
      continue;
    }
    h->SetDirectory(0);
    fRecoUtils->SetEMCALChannelTimeRecalibrationFactors(i,h);
  }

  delete contBC;

  return 1;
}

/**
 * Initialize the L1 phase time calibration.
 */
Int_t AliEmcalCorrectionCellTimeCalib::InitTimeCalibrationL1Phase()
{
  // Initialising run-by-run L1 phase in time calibration maps

  if (!fEvent)
    return 0;

  AliInfo("Initialising run-by-run L1 phase in time calibration map");

  // init default maps first
  if (!fRecoUtils->GetEMCALL1PhaseInTimeRecalibrationArray())
    fRecoUtils->InitEMCALL1PhaseInTimeRecalibration() ;

  Int_t runBC = fEvent->GetRunNumber();

  AliOADBContainer *contBC = new AliOADBContainer("");
  if (fBasePath!="")
  { //if fBasePath specified in the ->SetBasePath()
    AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));

    TFile *timeFile=new TFile(Form("%s/EMCALTimeL1PhaseCalib.root",fBasePath.Data()),"read");
    if (!timeFile || timeFile->IsZombie())
    {
      AliFatal(Form("EMCALTimeL1PhaseCalib.root was not found in the path provided: %s",fBasePath.Data()));
      return 0;
    }

    if (timeFile) delete timeFile;

    contBC->InitFromFile(Form("%s/EMCALTimeL1PhaseCalib.root",fBasePath.Data()),"AliEMCALTimeL1PhaseCalib");
  }
  else
  { // Else choose the one in the $ALICE_PHYSICS directory
    AliInfo("Loading L1 phase in time calibration OADB from $ALICE_PHYSICS/OADB/EMCAL");

    TFile *timeFile=new TFile("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeL1PhaseCalib.root","read");
    if (!timeFile || timeFile->IsZombie())
    {
      AliFatal("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeL1PhaseCalib.root was not found");
      return 0;
    }

    if (timeFile) delete timeFile;

    contBC->InitFromFile("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeL1PhaseCalib.root","AliEMCALTimeL1PhaseCalib");
  }

  TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
  if (!arrayBC)
  {
    AliError(Form("No external L1 phase in time calibration set for run number: %d", runBC));
    delete contBC;
    return 2;
  }

  // Only 1 L1 phase correction possible, except special cases
  TString pass = "pass1";

  if ( fFilepass=="muon_calo_pass1" && fRun > 209121 && fRun < 244284 )
    pass = "pass0";//period LHC15a-m

  TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(pass);
  if (!arrayBCpass)
  {
    AliError(Form("No external L1 phase in time calibration set for: %d -%s", runBC,pass.Data()));
    delete contBC;
    return 2;
  }

  arrayBCpass->Print();

  TH1C *h = fRecoUtils->GetEMCALL1PhaseInTimeRecalibrationForAllSM();
  if (h) delete h;

  h = (TH1C*)arrayBCpass->FindObject(Form("h%d",runBC));

  if (!h) {
    AliFatal(Form("There is no calibration histogram h%d for this run",runBC));
  }
  h->SetDirectory(0);
  fRecoUtils->SetEMCALL1PhaseInTimeRecalibrationForAllSM(h);

  delete contBC;

  return 1;
}

/**
 * This function is called if the run changes (it inherits from the base component),
 * to load a new time calibration and fill relevant variables.
 */
Bool_t AliEmcalCorrectionCellTimeCalib::CheckIfRunChanged()
{
  Bool_t runChanged = AliEmcalCorrectionComponent::CheckIfRunChanged();

  if (runChanged) {

    // define what recalib parameters are needed for various switches
    // this is based on implementation in AliEMCALRecoUtils
    Bool_t needTimecalib   = fCalibrateTime;
    if(fRun>209121) fCalibrateTimeL1Phase = kTRUE;
    Bool_t needTimecalibL1Phase = fCalibrateTime & fCalibrateTimeL1Phase;

    // init time calibration
    if (needTimecalib && fUseAutomaticTimeCalib) {
      Int_t initTC = InitTimeCalibration();
      if (!initTC) {
        AliError("InitTimeCalibration returned false, returning");
      }
      if (initTC==1) {
        AliWarning("InitTimeCalib OK");
      }
      if (initTC > 1) {
        AliWarning(Form("No external time calibration available: %d - %s", fEvent->GetRunNumber(), fFilepass.Data()));
      }
    }

    // init time calibration with L1 phase
    if (needTimecalibL1Phase && fUseAutomaticTimeCalib) {
      Int_t initTCL1Phase = InitTimeCalibrationL1Phase();
      if (!initTCL1Phase) {
        AliError("InitTimeCalibrationL1Phase returned false, returning");
      }
      if (initTCL1Phase==1) {
        AliWarning("InitTimeCalibL1Phase OK");
      }
      if (initTCL1Phase > 1) {
        AliWarning(Form("No external time calibration L1 phase available: %d - %s", fEvent->GetRunNumber(), fFilepass.Data()));
      }
    }
  }
  return runChanged;
}
<commit_msg>update pass naming scheme for calibration objects<commit_after>// AliEmcalCorrectionCellTimeCalib
//

#include <TObjArray.h>
#include <TFile.h>
#include "AliEMCALGeometry.h"
#include "AliOADBContainer.h"
#include "AliEMCALRecoUtils.h"
#include "AliAODEvent.h"

#include "AliEmcalCorrectionCellTimeCalib.h"

/// \cond CLASSIMP
ClassImp(AliEmcalCorrectionCellTimeCalib);
/// \endcond

// Actually registers the class with the base class
RegisterCorrectionComponent<AliEmcalCorrectionCellTimeCalib> AliEmcalCorrectionCellTimeCalib::reg("AliEmcalCorrectionCellTimeCalib");

/**
 * Default constructor
 */
AliEmcalCorrectionCellTimeCalib::AliEmcalCorrectionCellTimeCalib() :
  AliEmcalCorrectionComponent("AliEmcalCorrectionCellTimeCalib")
  ,fCalibrateTime(kFALSE)
  ,fCalibrateTimeL1Phase(kFALSE)
  ,fUseAutomaticTimeCalib(1)
  ,fCellTimeDistBefore(0)
  ,fCellTimeDistAfter(0)
{
}

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

/**
 * Initialize and configure the component.
 */
Bool_t AliEmcalCorrectionCellTimeCalib::Initialize()
{
  // Initialization
  AliEmcalCorrectionComponent::Initialize();

  AliWarning("Init EMCAL time calibration");

  GetProperty("createHistos", fCreateHisto);

  fCalibrateTime = kTRUE;

  // init reco utils
  if (!fRecoUtils)
    fRecoUtils  = new AliEMCALRecoUtils;

  fRecoUtils->SetPositionAlgorithm(AliEMCALRecoUtils::kPosTowerGlobal);

  return kTRUE;
}

/**
 * Create run-independent objects for output. Called before running over events.
 */
void AliEmcalCorrectionCellTimeCalib::UserCreateOutputObjects()
{
  AliEmcalCorrectionComponent::UserCreateOutputObjects();

  if (fCreateHisto){
    fCellTimeDistBefore = new TH1F("hCellTimeDistBefore","hCellTimeDistBefore;t_cell",1000,-10e-6,10e-6);
    fOutput->Add(fCellTimeDistBefore);
    fCellTimeDistAfter = new TH1F("hCellTimeDistAfter","hCellTimeDistAfter;t_cell",1000,-10e-6,10e-6);
    fOutput->Add(fCellTimeDistAfter);
  }
}

/**
 * Called for each event to process the event data.
 */
Bool_t AliEmcalCorrectionCellTimeCalib::Run()
{
  AliEmcalCorrectionComponent::Run();

  if (!fEvent) {
    AliError("Event ptr = 0, returning");
    return kFALSE;
  }

  CheckIfRunChanged();

  // CONFIGURE THE RECO UTILS -------------------------------------------------

  // allows time calibration
  if (fCalibrateTime)
    fRecoUtils->SwitchOnTimeRecalibration();
  else
    fRecoUtils->SwitchOffTimeRecalibration();

  // allows time calibration with L1 phase
  if (fCalibrateTimeL1Phase)
    fRecoUtils->SwitchOnL1PhaseInTimeRecalibration();
  else
    fRecoUtils->SwitchOffL1PhaseInTimeRecalibration();

  // START PROCESSING ---------------------------------------------------------
  // Test if cells present
  if (fCaloCells->GetNumberOfCells()<=0)
  {
    AliWarning(Form("Number of EMCAL cells = %d, returning", fCaloCells->GetNumberOfCells()));
    return kFALSE;
  }

  // mark the cells not recalibrated
  fRecoUtils->ResetCellsCalibrated();

  if(fCreateHisto)
    FillCellQA(fCellTimeDistBefore); // "before" QA

  // CELL RECALIBRATION -------------------------------------------------------
  // cell objects will be updated
  UpdateCells();

  if(fCreateHisto)
    FillCellQA(fCellTimeDistAfter); // "after" QA

  return kTRUE;
}

/**
 * Initialize the time calibration.
 */
Int_t AliEmcalCorrectionCellTimeCalib::InitTimeCalibration()
{
  // Initialising bad channel maps

  if (!fEvent)
    return 0;

  AliInfo("Initialising time calibration map");

  // init default maps first
  if (!fRecoUtils->GetEMCALTimeRecalibrationFactorsArray())
    fRecoUtils->InitEMCALTimeRecalibrationFactors() ;

  Int_t runBC = fEvent->GetRunNumber();

  AliOADBContainer *contBC = new AliOADBContainer("");
  if (fBasePath!="")
  { //if fBasePath specified in the ->SetBasePath()
    AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));

    TFile *fbad=new TFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"read");
    if (!fbad || fbad->IsZombie())
    {
      AliFatal(Form("EMCALTimeCalib.root was not found in the path provided: %s",fBasePath.Data()));
      return 0;
    }

    if (fbad) delete fbad;

    contBC->InitFromFile(Form("%s/EMCALTimeCalib.root",fBasePath.Data()),"AliEMCALTimeCalib");
  }
  else
  { // Else choose the one in the $ALICE_PHYSICS directory
    AliInfo("Loading time calibration OADB from $ALICE_PHYSICS/OADB/EMCAL");

    TFile *fbad=new TFile("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeCalib.root","read");
    if (!fbad || fbad->IsZombie())
    {
      AliFatal("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeCalib.root was not found");
      return 0;
    }

    if (fbad) delete fbad;

    contBC->InitFromFile("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeCalib.root","AliEMCALTimeCalib");
  }

  TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
  if (!arrayBC)
  {
    AliError(Form("No external time calibration set for run number: %d", runBC));
    delete contBC;
    return 2;
  }

  // The calibration object is accessed by specifying a pass
  // For run 1, the actual pass is used (fFilepass, as determined in AliEmcalCorrectionComponent::GetPass())
  // For run 2, the pass is always set to pass1 (as a convention)
  // Other exceptions are hard-coded below

  TString pass = fFilepass;
  if (fFilepass=="spc_calo") pass = "pass3";
  if (fRun > 209121) pass = "pass1";

  TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(pass);
  if (!arrayBCpass)
  {
    AliError(Form("No external time calibration set for: %d -%s", runBC,pass.Data()));
    delete contBC;
    return 2;
  }

  arrayBCpass->Print();

  for(Int_t i = 0; i < 4; i++)
  {
    TH1F *h = fRecoUtils->GetEMCALChannelTimeRecalibrationFactors(i);
    if (h)
      delete h;

    h = (TH1F*)arrayBCpass->FindObject(Form("hAllTimeAvBC%d",i));

    if (!h)
    {
      AliError(Form("Can not get hAllTimeAvBC%d",i));
      continue;
    }
    h->SetDirectory(0);
    fRecoUtils->SetEMCALChannelTimeRecalibrationFactors(i,h);
  }

  delete contBC;

  return 1;
}

/**
 * Initialize the L1 phase time calibration.
 */
Int_t AliEmcalCorrectionCellTimeCalib::InitTimeCalibrationL1Phase()
{
  // Initialising run-by-run L1 phase in time calibration maps

  if (!fEvent)
    return 0;

  AliInfo("Initialising run-by-run L1 phase in time calibration map");

  // init default maps first
  if (!fRecoUtils->GetEMCALL1PhaseInTimeRecalibrationArray())
    fRecoUtils->InitEMCALL1PhaseInTimeRecalibration() ;

  Int_t runBC = fEvent->GetRunNumber();

  AliOADBContainer *contBC = new AliOADBContainer("");
  if (fBasePath!="")
  { //if fBasePath specified in the ->SetBasePath()
    AliInfo(Form("Loading time calibration OADB from given path %s",fBasePath.Data()));

    TFile *timeFile=new TFile(Form("%s/EMCALTimeL1PhaseCalib.root",fBasePath.Data()),"read");
    if (!timeFile || timeFile->IsZombie())
    {
      AliFatal(Form("EMCALTimeL1PhaseCalib.root was not found in the path provided: %s",fBasePath.Data()));
      return 0;
    }

    if (timeFile) delete timeFile;

    contBC->InitFromFile(Form("%s/EMCALTimeL1PhaseCalib.root",fBasePath.Data()),"AliEMCALTimeL1PhaseCalib");
  }
  else
  { // Else choose the one in the $ALICE_PHYSICS directory
    AliInfo("Loading L1 phase in time calibration OADB from $ALICE_PHYSICS/OADB/EMCAL");

    TFile *timeFile=new TFile("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeL1PhaseCalib.root","read");
    if (!timeFile || timeFile->IsZombie())
    {
      AliFatal("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeL1PhaseCalib.root was not found");
      return 0;
    }

    if (timeFile) delete timeFile;

    contBC->InitFromFile("$ALICE_PHYSICS/OADB/EMCAL/EMCALTimeL1PhaseCalib.root","AliEMCALTimeL1PhaseCalib");
  }

  TObjArray *arrayBC=(TObjArray*)contBC->GetObject(runBC);
  if (!arrayBC)
  {
    AliError(Form("No external L1 phase in time calibration set for run number: %d", runBC));
    delete contBC;
    return 2;
  }

  // The calibration object is accessed by specifying a pass
  // For run 2 (which is the only time L1-phase is implemented), the pass is always set to pass1 (as a convention)
  // Other exceptions are hard-coded below

  TString pass = "pass1";

  if ( fFilepass=="muon_calo_pass1" && fRun > 209121 && fRun < 244284 )
    pass = "pass0";//period LHC15a-m

  TObjArray *arrayBCpass=(TObjArray*)arrayBC->FindObject(pass);
  if (!arrayBCpass)
  {
    AliError(Form("No external L1 phase in time calibration set for: %d -%s", runBC,pass.Data()));
    delete contBC;
    return 2;
  }

  arrayBCpass->Print();

  TH1C *h = fRecoUtils->GetEMCALL1PhaseInTimeRecalibrationForAllSM();
  if (h) delete h;

  h = (TH1C*)arrayBCpass->FindObject(Form("h%d",runBC));

  if (!h) {
    AliFatal(Form("There is no calibration histogram h%d for this run",runBC));
  }
  h->SetDirectory(0);
  fRecoUtils->SetEMCALL1PhaseInTimeRecalibrationForAllSM(h);

  delete contBC;

  return 1;
}

/**
 * This function is called if the run changes (it inherits from the base component),
 * to load a new time calibration and fill relevant variables.
 */
Bool_t AliEmcalCorrectionCellTimeCalib::CheckIfRunChanged()
{
  Bool_t runChanged = AliEmcalCorrectionComponent::CheckIfRunChanged();

  if (runChanged) {

    // define what recalib parameters are needed for various switches
    // this is based on implementation in AliEMCALRecoUtils
    Bool_t needTimecalib   = fCalibrateTime;
    if(fRun>209121) fCalibrateTimeL1Phase = kTRUE;
    Bool_t needTimecalibL1Phase = fCalibrateTime & fCalibrateTimeL1Phase;

    // init time calibration
    if (needTimecalib && fUseAutomaticTimeCalib) {
      Int_t initTC = InitTimeCalibration();
      if (!initTC) {
        AliError("InitTimeCalibration returned false, returning");
      }
      if (initTC==1) {
        AliWarning("InitTimeCalib OK");
      }
      if (initTC > 1) {
        AliWarning(Form("No external time calibration available: %d - %s", fEvent->GetRunNumber(), fFilepass.Data()));
      }
    }

    // init time calibration with L1 phase
    if (needTimecalibL1Phase && fUseAutomaticTimeCalib) {
      Int_t initTCL1Phase = InitTimeCalibrationL1Phase();
      if (!initTCL1Phase) {
        AliError("InitTimeCalibrationL1Phase returned false, returning");
      }
      if (initTCL1Phase==1) {
        AliWarning("InitTimeCalibL1Phase OK");
      }
      if (initTCL1Phase > 1) {
        AliWarning(Form("No external time calibration L1 phase available: %d - %s", fEvent->GetRunNumber(), fFilepass.Data()));
      }
    }
  }
  return runChanged;
}
<|endoftext|>


<commit_before>#include "dispatcher_utility.hpp"
#include "hid_manager.hpp"

namespace {
class control_led final : public pqrs::dispatcher::extra::dispatcher_client {
public:
  control_led(const control_led&) = delete;

  control_led(bool led_state) : dispatcher_client() {
    std::vector<std::pair<krbn::hid_usage_page, krbn::hid_usage>> targets({
        std::make_pair(krbn::hid_usage_page::generic_desktop, krbn::hid_usage::gd_keyboard),
    });

    hid_manager_ = std::make_unique<krbn::hid_manager>(targets);

    hid_manager_->device_detected.connect([led_state](auto&& weak_hid) {
      if (auto hid = weak_hid.lock()) {
        krbn::logger::get_logger().info("{0} is detected.", hid->get_name_for_log());

        hid->opened.connect([led_state, weak_hid] {
          if (auto hid = weak_hid.lock()) {
            hid->async_set_caps_lock_led_state(led_state ? krbn::led_state::on : krbn::led_state::off);
            krbn::logger::get_logger().info("async_set_caps_lock_led_state is called.");
          }
        });

        hid->open_failed.connect([weak_hid](auto&& error_code) {
          if (auto hid = weak_hid.lock()) {
            krbn::logger::get_logger().error("failed to open {0}", hid->get_name_for_log());
          }
        });

        hid->async_open();
      }
    });

    hid_manager_->async_start();
  }

  virtual ~control_led(void) {
    detach_from_dispatcher([this] {
      hid_manager_ = nullptr;
    });
  }

private:
  std::unique_ptr<krbn::hid_manager> hid_manager_;
};
} // namespace

int main(int argc, const char* argv[]) {
  krbn::dispatcher_utility::initialize_dispatchers();

  signal(SIGINT, [](int) {
    CFRunLoopStop(CFRunLoopGetMain());
  });

  if (getuid() != 0) {
    krbn::logger::get_logger().error("control_led requires root privilege.");
    return 1;
  }

  if (argc == 1) {
    krbn::logger::get_logger().error("Usage: control_led on|off");
    krbn::logger::get_logger().error("  Example: control_led on");
    krbn::logger::get_logger().error("  Example: control_led off");
    return 1;
  }

  auto p = std::make_unique<control_led>(std::string(argv[1]) == "on");

  // ------------------------------------------------------------

  CFRunLoopRun();

  // ------------------------------------------------------------

  p = nullptr;

  krbn::dispatcher_utility::terminate_dispatchers();

  return 0;
}
<commit_msg>update appendix/control_led<commit_after>#include "dispatcher_utility.hpp"
#include "hid_manager.hpp"

namespace {
class control_led final : public pqrs::dispatcher::extra::dispatcher_client {
public:
  control_led(const control_led&) = delete;

  control_led(bool led_state) : dispatcher_client() {
    std::vector<std::pair<krbn::hid_usage_page, krbn::hid_usage>> targets({
        std::make_pair(krbn::hid_usage_page::generic_desktop, krbn::hid_usage::gd_keyboard),
    });

    hid_manager_ = std::make_unique<krbn::hid_manager>(targets);

    hid_manager_->device_detected.connect([led_state](auto&& weak_hid) {
      if (auto hid = weak_hid.lock()) {
        krbn::logger::get_logger().info("{0} is detected.", hid->get_name_for_log());

        hid->opened.connect([led_state, weak_hid] {
          if (auto hid = weak_hid.lock()) {
            hid->async_set_caps_lock_led_state(led_state ? krbn::led_state::on : krbn::led_state::off);
            krbn::logger::get_logger().info("async_set_caps_lock_led_state is called.");
          }
        });

        hid->open_failed.connect([weak_hid](auto&& error_code) {
          if (auto hid = weak_hid.lock()) {
            krbn::logger::get_logger().error("failed to open {0}", hid->get_name_for_log());
          }
        });

        hid->async_open();
      }
    });

    hid_manager_->async_start();
  }

  virtual ~control_led(void) {
    detach_from_dispatcher([this] {
      hid_manager_ = nullptr;
    });
  }

private:
  std::unique_ptr<krbn::hid_manager> hid_manager_;
};
} // namespace

int main(int argc, const char* argv[]) {
  krbn::dispatcher_utility::initialize_dispatchers();

  signal(SIGINT, [](int) {
    CFRunLoopStop(CFRunLoopGetMain());
  });

  if (getuid() != 0) {
    krbn::logger::get_logger().error("control_led requires root privilege.");
  } else {
    if (argc == 1) {
      krbn::logger::get_logger().error("Usage: control_led on|off");
      krbn::logger::get_logger().error("  Example: control_led on");
      krbn::logger::get_logger().error("  Example: control_led off");
    } else {
      auto p = std::make_unique<control_led>(std::string(argv[1]) == "on");

      CFRunLoopRun();

      p = nullptr;
    }
  }

  krbn::dispatcher_utility::terminate_dispatchers();

  return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, development version     *
*                (c) 2006-2017 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 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 Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this program. If not, see <http://www.gnu.org/licenses/>.        *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_MAPPING_IDENTITYMAPPING_INL
#define SOFA_COMPONENT_MAPPING_IDENTITYMAPPING_INL

#include <SofaBaseMechanics/IdentityMapping.h>
#include <sofa/defaulttype/RigidTypes.h>
#include <sofa/defaulttype/VecTypes.h>

namespace sofa
{

namespace component
{

namespace mapping
{

template<class TIn, class TOut>
void IdentityMapping<TIn, TOut>::init()
{
    const unsigned n = this->fromModel->getSize();

    this->toModel->resize( n );

    Inherit::init();

    // build J
    {
        static const unsigned N = std::min<unsigned>(NIn, NOut);

        J.compressedMatrix.resize( n*NOut, n*NIn );
        J.compressedMatrix.reserve( n*N );

        for( size_t i=0 ; i<n ; ++i )
        {
            for(unsigned r = 0; r < N; ++r)
            {
                const unsigned row = NOut * i + r;
                J.compressedMatrix.startVec( row );
                const unsigned col = NIn * i + r;
                J.compressedMatrix.insertBack( row, col ) = (OutReal)1;
            }
        }
        J.compressedMatrix.finalize();
    }

}

template <class TIn, class TOut>
void IdentityMapping<TIn, TOut>::apply(const core::MechanicalParams * /*mparams*/, Data<VecCoord>& dOut, const Data<InVecCoord>& dIn)
{
    helper::WriteOnlyAccessor< Data<VecCoord> > out = dOut;
    helper::ReadAccessor< Data<InVecCoord> > in = dIn;

    if(out.size() != in.size()) // true if topological changes
    {
        out.resize(in.size());
    }

    for(unsigned int i=0; i<out.size(); i++)
    {
        helper::eq(out[i], in[i]);
    }
}

template <class TIn, class TOut>
void IdentityMapping<TIn, TOut>::applyJ(const core::MechanicalParams * /*mparams*/, Data<VecDeriv>& dOut, const Data<InVecDeriv>& dIn)
{
    helper::WriteOnlyAccessor< Data<VecDeriv> > out = dOut;
    helper::ReadAccessor< Data<InVecDeriv> > in = dIn;

    if(out.size() != in.size()) // true if topological changes
    {
        out.resize(in.size());
    }

    for( size_t i=0 ; i<this->maskTo->size() ; ++i)
    {
        if( !this->maskTo->isActivated() || this->maskTo->getEntry(i) )
            helper::eq(out[i], in[i]);
    }
}

template<class TIn, class TOut>
void IdentityMapping<TIn, TOut>::applyJT(const core::MechanicalParams * /*mparams*/, Data<InVecDeriv>& dOut, const Data<VecDeriv>& dIn)
{
    helper::WriteAccessor< Data<InVecDeriv> > out = dOut;
    helper::ReadAccessor< Data<VecDeriv> > in = dIn;

    for( size_t i=0 ; i<this->maskTo->size() ; ++i)
    {
        if( this->maskTo->getEntry(i) )
            helper::peq(out[i], in[i]);
    }
}

template <class TIn, class TOut>
void IdentityMapping<TIn, TOut>::applyJT(const core::ConstraintParams * /*cparams*/, Data<InMatrixDeriv>& dOut, const Data<MatrixDeriv>& dIn)
{
    InMatrixDeriv& out = *dOut.beginEdit();
    const MatrixDeriv& in = dIn.getValue();

    typename Out::MatrixDeriv::RowConstIterator rowItEnd = in.end();

    for (typename Out::MatrixDeriv::RowConstIterator rowIt = in.begin(); rowIt != rowItEnd; ++rowIt)
    {
        typename Out::MatrixDeriv::ColConstIterator colIt = rowIt.begin();
        typename Out::MatrixDeriv::ColConstIterator colItEnd = rowIt.end();

        // Creates a constraints if the input constraint is not empty.
        if (colIt != colItEnd)
        {
            typename In::MatrixDeriv::RowIterator o = out.writeLine(rowIt.index());

            while (colIt != colItEnd)
            {
                InDeriv data;
                helper::eq(data, colIt.val());

                o.addCol(colIt.index(), data);

                ++colIt;
            }
        }
    }

    dOut.endEdit();
}

template <class TIn, class TOut>
void IdentityMapping<TIn, TOut>::handleTopologyChange()
{
    if ( this->toModel && this->fromModel && this->toModel->getSize() != this->fromModel->getSize()) this->init();
}

//template <class TIn, class TOut>
//void IdentityMapping<TIn, TOut>::updateJ()
//{
//    size_t currentHash = this->maskTo->getHash();
//    if(  previousMaskHash!=currentHash )
//    {
//        previousMaskHash = currentHash;

//        assert( this->fromModel->getSize() == this->toModel->getSize());

//        static const unsigned N = std::min<unsigned>(NIn, NOut);

//        J.compressedMatrix.setZero();

//        for( size_t i=0 ; i<this->toModel->getSize() ; ++i )
//        {
//            for(unsigned r = 0; r < N; ++r)
//            {
//                if( this->maskTo->getEntry(i) )
//                {
//                    const unsigned row = NOut * i + r;
//                    const unsigned col = NIn * i + r;
//                    J.compressedMatrix.insert( row, col ) = (OutReal)1;
//                }
//            }
//        }
//    }
//}

template <class TIn, class TOut>
const sofa::defaulttype::BaseMatrix* IdentityMapping<TIn, TOut>::getJ()
{
//    updateJ();
    return &J;
}

template <class TIn, class TOut>
const typename IdentityMapping<TIn, TOut>::js_type* IdentityMapping<TIn, TOut>::getJs()
{
//    updateJ();
    return &Js;
}

template<class TIn, class TOut>
void IdentityMapping<TIn, TOut>::updateForceMask()
{
    for( size_t i = 0 ; i<this->maskTo->size() ; ++i )
        if( this->maskTo->getEntry(i) )this->maskFrom->insertEntry( i );

}

} // namespace mapping

} // namespace component

} // namespace sofa

#endif
<commit_msg>[SofaKernel] REVERT commit cf5a31a50f9cb1c6897c7b39c52d0b4034412efb<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, development version     *
*                (c) 2006-2017 INRIA, USTL, UJF, CNRS, MGH                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 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 Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this program. If not, see <http://www.gnu.org/licenses/>.        *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_MAPPING_IDENTITYMAPPING_INL
#define SOFA_COMPONENT_MAPPING_IDENTITYMAPPING_INL

#include <SofaBaseMechanics/IdentityMapping.h>
#include <sofa/defaulttype/RigidTypes.h>
#include <sofa/defaulttype/VecTypes.h>

namespace sofa
{

namespace component
{

namespace mapping
{

template<class TIn, class TOut>
void IdentityMapping<TIn, TOut>::init()
{
    const unsigned n = this->fromModel->getSize();

    this->toModel->resize( n );

    Inherit::init();

    // build J
    {
        static const unsigned N = std::min<unsigned>(NIn, NOut);

        J.compressedMatrix.resize( n*NOut, n*NIn );
        J.compressedMatrix.reserve( n*N );

        for( size_t i=0 ; i<n ; ++i )
        {
            for(unsigned r = 0; r < N; ++r)
            {
                const unsigned row = NOut * i + r;
                J.compressedMatrix.startVec( row );
                const unsigned col = NIn * i + r;
                J.compressedMatrix.insertBack( row, col ) = (OutReal)1;
            }
        }
        J.compressedMatrix.finalize();
    }

}

template <class TIn, class TOut>
void IdentityMapping<TIn, TOut>::apply(const core::MechanicalParams * /*mparams*/, Data<VecCoord>& dOut, const Data<InVecCoord>& dIn)
{
    helper::WriteOnlyAccessor< Data<VecCoord> > out = dOut;
    helper::ReadAccessor< Data<InVecCoord> > in = dIn;

    for(unsigned int i=0; i<out.size(); i++)
    {
        helper::eq(out[i], in[i]);
    }
}

template <class TIn, class TOut>
void IdentityMapping<TIn, TOut>::applyJ(const core::MechanicalParams * /*mparams*/, Data<VecDeriv>& dOut, const Data<InVecDeriv>& dIn)
{
    helper::WriteOnlyAccessor< Data<VecDeriv> > out = dOut;
    helper::ReadAccessor< Data<InVecDeriv> > in = dIn;

    for( size_t i=0 ; i<this->maskTo->size() ; ++i)
    {
        if( !this->maskTo->isActivated() || this->maskTo->getEntry(i) )
            helper::eq(out[i], in[i]);
    }
}

template<class TIn, class TOut>
void IdentityMapping<TIn, TOut>::applyJT(const core::MechanicalParams * /*mparams*/, Data<InVecDeriv>& dOut, const Data<VecDeriv>& dIn)
{
    helper::WriteAccessor< Data<InVecDeriv> > out = dOut;
    helper::ReadAccessor< Data<VecDeriv> > in = dIn;

    for( size_t i=0 ; i<this->maskTo->size() ; ++i)
    {
        if( this->maskTo->getEntry(i) )
            helper::peq(out[i], in[i]);
    }
}

template <class TIn, class TOut>
void IdentityMapping<TIn, TOut>::applyJT(const core::ConstraintParams * /*cparams*/, Data<InMatrixDeriv>& dOut, const Data<MatrixDeriv>& dIn)
{
    InMatrixDeriv& out = *dOut.beginEdit();
    const MatrixDeriv& in = dIn.getValue();

    typename Out::MatrixDeriv::RowConstIterator rowItEnd = in.end();

    for (typename Out::MatrixDeriv::RowConstIterator rowIt = in.begin(); rowIt != rowItEnd; ++rowIt)
    {
        typename Out::MatrixDeriv::ColConstIterator colIt = rowIt.begin();
        typename Out::MatrixDeriv::ColConstIterator colItEnd = rowIt.end();

        // Creates a constraints if the input constraint is not empty.
        if (colIt != colItEnd)
        {
            typename In::MatrixDeriv::RowIterator o = out.writeLine(rowIt.index());

            while (colIt != colItEnd)
            {
                InDeriv data;
                helper::eq(data, colIt.val());

                o.addCol(colIt.index(), data);

                ++colIt;
            }
        }
    }

    dOut.endEdit();
}

template <class TIn, class TOut>
void IdentityMapping<TIn, TOut>::handleTopologyChange()
{
    if ( this->toModel && this->fromModel && this->toModel->getSize() != this->fromModel->getSize()) this->init();
}

//template <class TIn, class TOut>
//void IdentityMapping<TIn, TOut>::updateJ()
//{
//    size_t currentHash = this->maskTo->getHash();
//    if(  previousMaskHash!=currentHash )
//    {
//        previousMaskHash = currentHash;

//        assert( this->fromModel->getSize() == this->toModel->getSize());

//        static const unsigned N = std::min<unsigned>(NIn, NOut);

//        J.compressedMatrix.setZero();

//        for( size_t i=0 ; i<this->toModel->getSize() ; ++i )
//        {
//            for(unsigned r = 0; r < N; ++r)
//            {
//                if( this->maskTo->getEntry(i) )
//                {
//                    const unsigned row = NOut * i + r;
//                    const unsigned col = NIn * i + r;
//                    J.compressedMatrix.insert( row, col ) = (OutReal)1;
//                }
//            }
//        }
//    }
//}

template <class TIn, class TOut>
const sofa::defaulttype::BaseMatrix* IdentityMapping<TIn, TOut>::getJ()
{
//    updateJ();
    return &J;
}

template <class TIn, class TOut>
const typename IdentityMapping<TIn, TOut>::js_type* IdentityMapping<TIn, TOut>::getJs()
{
//    updateJ();
    return &Js;
}

template<class TIn, class TOut>
void IdentityMapping<TIn, TOut>::updateForceMask()
{
    for( size_t i = 0 ; i<this->maskTo->size() ; ++i )
        if( this->maskTo->getEntry(i) )this->maskFrom->insertEntry( i );

}

} // namespace mapping

} // namespace component

} // namespace sofa

#endif
<|endoftext|>